[MySQL i PHP] Zapytanie w MySQL działa a w PHP nie

0

Mam taki kodzik służący do logowania użytkowników:

@ $baza = mysql_pconnect(localhost, x, "x");

if($baza == false)
{
	print("Błąd: Brak połączenia z bazą danych\n");
	exit();
}

if($_GET["user"] != "" && $_GET["pass"] != "")
{
	$query = "select * from user where pseudo='".$_GET["user"]."' and haslo=password('".$_GET["pass"]."');";
	
	echo $query;
	
	$wynik = mysql_query($query);
	
	if($wynik)
	{
		$allow = true;
		session_register("allow");
	} else
	{
		echo "Informacje nie zgadzają się";
	}
}

Apache daje mi do zrozumienia, że dla $query nie ma wyników, a gdy skopiuję wyświetloną linijkę i wpisze ją do MySQL, to otrzymuje prawidłowy wynik, czyli jeden rekord z danymi użytkownika. To trochę absurdalne, żeby to samo nie działało w PHP i działało w MySQL. Co jest nie tak jak być powinno?

0

po:

1. Zle sformulowany warunek: if($_GET["user"] != "" && $_GET["pass"] != "")

operator && ma wyzszy priorytet niz operator != takze ogolem z puktu widzenia powyzszy warunek ma taka postac: if(($_GET["user"] != "" && $_GET["pass"]) != "")
jak widzisz chyba mija sie z celem ;]
Tak jest poprawnie:
if(($_GET["user"] != "") && ($_GET["pass"] != ""))

2. ten warunek z $wynik kompletnie zle sformulowany tak sie nie spradza czy zapytanie zwrocilo jakies rekordy czy nie... do tego sluzy mysql_num_rows($wynik) samo wynik zapytania jest prawdziwy nawet jesli w tabeli nie ma zadnych rekordow albo nieznaleziono zadnych zapytanei zwraca FALSE tylko w wypadku bledu w zapytaniu lub odnoszeniu sie do nieistniejacej kolumny czy tez tabeli rowniez gdy nie jestesmy podlaczeni do bazy.

3. srednik w zapytaniu ;]
usun go i bedzie dobrze ale popraw kolejne bledy ktore wymienilem wczesniej bo powrocisz do punktu wyjscia ;]

4. RTFM! :|

0

ja bym jeszcze proponował nie wstawiać bezpośrednio z tablicy

$_GET

do zapytania, bo ci ktoś walnie

$user= "Admin' OR '1'='1' --"

i ma pełną kontrolę nad serwisem...

0

mysle ze takie cos w ogóle nie jest dobre :-|

Osobiscie uzywam czegos takiego, ze wczytuje z bazy wszystkie nicki z $_POST['login'], po wcześniejszym ograniczeniu wykorzystanych znaków do liter i cyfr, jeśli zwróci mniej lub więcej niż 1 rekord to "zły login lub hasło", a jak będzie jeden, to z otrzymanego rekordu odczytuje zahashowane haslo (md5) i porownuje z hashem md5($_POST['haslo'])...

dobrze robie? :)

0

Próbowałem juz mysql_num_rows i dostałem odpowiedź:

select * from user where pseudo='x' and haslo=password('x')

Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in /usr/local/apache2/htdocs/farmians/index.php on line 102

Informacje nie zgadzają się

Dodałem nawiasy, zmieniłem warunek z $wynik na $i == 1 i dodałem linijkę:

$i = mysql_num_rows($wynik);

Średnik ze stringa w $query usunąłem, jednak to absolutnie nic nie zmieniło. Dodałem i nie zaobserwowałem żadnych zmian. Sprawdziłem czy $wynik po wykonaniu mysql_query() i czy $i maja jaką bądź wartość i nic. Obydwie są puste. Luknę jeszcze do jakiego manuala, ale według mnie w czym innym tkwi problem.

//dopisane
Ojojojojojojoj trochę mocno zmaściłem [wstyd] . Sorry, że zawracam głowę. Znalazłem błąd [green] . Po prostu chciałem wykonać polecenie select, bez uprzedniego wykonania funkcji mysql_select_db() :/ :D . Dzięki za wszystkie odpowiedzi. Nie do końca jarzę dlaczego wpisanie 'admin'OR1=1 pozwala przejąć kontrolę :|

0

może po prostu nie admin, ale nick admina... prostu się zalogójesz na konto admina...

0

Nie do końca jarzę dlaczego wpisanie 'admin'OR1=1 pozwala przejąć kontrolę

Google, polecam. Pierwsze linki [rotfl]

0
tomkiewicz napisał(a)

Osobiscie uzywam czegos takiego, ze wczytuje z bazy wszystkie nicki z $_POST['login'], po wcześniejszym ograniczeniu wykorzystanych znaków do liter i cyfr, jeśli zwróci mniej lub więcej niż 1 rekord to "zły login lub hasło", a jak będzie jeden, to z otrzymanego rekordu odczytuje zahashowane haslo (md5) i porownuje z hashem md5($_POST['haslo'])...

dobrze robie? :)

Dobrze (jeśli dobrze zrozumiałem, jak to robisz), ale szybsze jest coś takiego: wysyłasz zapytanie do serwera z wynikiem funkcji md5 dla podanego przez usera hasła. Jednocześnie blokujesz możliwość jakichś przekrętów w przeciwieństwie do wysłania w zapytaniu '(...) MD5(''.$hasło.'') (...)'. A to dlatego, że w sumie kontrolnej nigdy nie znajdzie się apostrof ani nawias, więc nie można takiego obejścia zrobić o jakim wyżej była mowa.
W podanym przeze mnie sposobie możesz dać tylko SELECT id FROM ..., bo reszta pól Ci jest niepotrzebna, więc ograniczasz transfer skrypt<->baza danych i dodatkowo potem sprawdzasz tylko mysql_num_rows().

0
Adam.Pilorz napisał(a)

możesz dać tylko SELECT id FROM ..., bo reszta pól Ci jest niepotrzebna (...) potem sprawdzasz tylko mysql_num_rows().

hmm niezly pomysl (ze tez ja na to nie wpadlem;)), ale co jesli istnieja dwa loginy o identycznym hasle? :P. Dlatego oprocz ID, nalezy pobrac z bazy tez login... no chyba ze id to jest wlasnie login, ale ja np. nie stosuje czegos takiego, bo duzo latwiej (tak mysle ;)) jest zarzadzac userami po cyfrowym ID, niz literowym loginie.

przyklad: duzo lepiej wyglada link do kolesia o nicku "Ma$ter 0f ch@c|<ing"

"profile_1234.htm"

niz "profile_Ma$ter%200f%20ch@c|%3Cing.htm",

albo w ogole (heh dzieki temu <ort>forom [:P - Ł]</ort>zorientowalem sie ze to sie pisze oddzielnie :D):
"/strona/php/profil.php?login=Ma$ter%200f%20ch@c|%3Cing&mode=no_admin" :D

ale to tak na marginesie, zeby sie nie nacial ktos, kto bedzie pisal swoja pierwsza stronke...

0

Nie, nie musisz dodawać login do zapytania, tylk opo prostu dajesz Where login=`.$tutaj_login_oczywiscie_zabezpieczony_przed_SQL_injection.'' AND passwd=`.md5($_GET['password']).''' czy coś w tym stylu :]

0

mozesz wykorzystac funkcje crc32 aby wygenerowac ID z loginu i na jego podstawie tez wykonywac pozniej logowanie i masz zarowno problem z unikalnym ID dla kazdego wiersza rozwiazany jak i ten drugi ;)

0

Nie do końca jarzę dlaczego wpisanie 'admin'OR1=1 pozwala przejąć kontrolę

Jak kiedys sie bedziesz uczyl logiki, to dowiesz sie, ze aby dla ALTERNATYWY zdanie bylo prawdziwe, prawdziwy musi byc chociaz jeden warunek. 1=1 zawsze jest prawdziwe wiec mysql zwroci rekord.

1 użytkowników online, w tym zalogowanych: 0, gości: 1