Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Bez[ieczny formularz logowania
Forum PHP.pl > Forum > Przedszkole
!*!
Zdaję sobie sprawę że dużo już takich tematów było, jednak interesuje mnie Wasza opinia na temat kodu mojego autorstwa, czy jest to w pełni bezpieczne, co należałoby poprawić w tej kewsti oraz w optymalnym działaniu.

  1. <?php
  2.  
  3.  
  4. // zabezpieczenie danych odebranych z $_POST
  5. function zgp($danezget){return htmlspecialchars(strip_tags(trim(stripslashes($danezget))));}
  6. // zabezpieczenie danych wysyłanych do bazy
  7. function wds($zrodlo){return htmlspecialchars(mysql_real_escape_string(trim($zrodlo)));}
  8.  
  9. // odbieranie i sprawdzenie danych z formularza $_POST
  10. if (isset($_POST['signin'])){
  11.  
  12. if (isset($_POST['login']) && isset($_POST['password'])){ //sprawdzenie czy login i hasło zostało przesłane
  13.  
  14. $login = zgp($_POST['login']); //oczyszczenie funkcją
  15. $password = $_POST['password'];
  16.  
  17. //sprawdzanie loginu
  18. $loginnotallowed = array( 'admin', 'administrator', 'admini', 'root', 'reboot', 'poweroff', ' ');
  19. if(in_array($login, $loginnotallowed)) {$error=1; echo 'Wybrany login jest zablokowany.';} //porównanie loginu z listy zablokowanej
  20. if (empty($login)) {$error=1; echo 'Wypełnij pole login.';} //sprawdza czy pole jest puste
  21. if(!preg_match("/[a-z0-9_]/",$login)){$error=1; echo 'Wpisałeś niedozwolone znaki';} // tylko małe litery i liczby oraz dolny myślink
  22. if(preg_match("/[A-Z]/",$login)){$error=1; echo 'Tylko małe litery.';} // błąd w przypadku wpisania dużych liter
  23. if(preg_match("/[\s\r\n]/",$login)){$error=1; echo 'Login nie może zawierać spacji.';} //błąd w przypadku użycia spacji
  24.  
  25. //sprawdzanie hasła
  26. if (empty($password)) {$error=1; echo 'Wypełnij pole hasło.';} //sprawdza czy pole jest puste
  27. echo '<br />';var_dump ($error);echo '<br />';echo $error;
  28.  
  29. if (!$error){// jeśli zadny z powyrzszych ifów nie zwrócił błedu $error = 1;
  30.  
  31. require_once('connect.php'); //połaczenie z bazą
  32.  
  33. $login = wds($_POST['login']); //oczyszczenie funkcją wysyłającą do bazy
  34. $password = md5($_POST['password']); //kodowanie md5
  35.  
  36. $sprawdzlogin = mysql_query("SELECT id, login, password FROM userlogin WHERE login = '$login' AND password = '$password' LIMIT 1");
  37. $wyniksprawdz = mysql_num_rows($sprawdzlogin); //sprawdzanie loginu i hasła
  38.  
  39. if(!$wyniksprawdz){//sprawdzanie wynikiu odebranego z bazy
  40. $errordb=1; echo 'nieprawidłowy login lub hasło';
  41. }
  42.  
  43. if(!$errordb){echo '!logowanie';}
  44.  
  45.  
  46.  
  47. }
  48.  
  49. }//koniec sprawdzania danych login - hasło
  50.  
  51. }//koniec sprawdzania danych
mac_fly
Wygląda ok, ale możesz "posolić" hasła dla bezpieczeństwa, lub od obecnego hasła(w md5) odjąć kilka znaków - dużo jest możliwości. winksmiley.jpg
!*!
A i jeszcze czy mógłbyś/moglibyście mi powiedzieć czy zastosowanie

Kod
if(!$wyniksprawdz)


Jest porpawne przy odbieraniu/sprawdzaniu danych z bazy, czy się zgadzają... wcześniej używałem

Kod
if($wyniksprawdz == 0)


Jednak ktoś mi powiedział że powinno się to robić na zasadzie takiej jakiej tu użyłem. Jednak nie jestem pewien czy jest to dobrze zrobione.
mac_fly
Obie są poprawne, a dla testu możesz napisać taki przykładowy kod:
  1. <?php
  2. $wynik=0;// zobaczysz napis nie działa, następnie jak odpalisz ten skrypt zmień na $wynik=1;
  3. if(!$wynik)
  4. {
  5. echo"nie dziala";
  6. }
  7. else
  8. {
  9. echo'dziala';
  10. }
  11. ?>
iVorIus
  1. $login = zgp($_POST['login']); //oczyszczenie funkcją
  2. $password = $_POST['password'];
  3. (...)
  4. login = wds($_POST['login']); //oczyszczenie funkcją wysyłającą do bazy
  5. $password = md5($_POST['password']); //kodowanie md5

Dlaczego hasła też nie oczyszczasz?
!*!
Ponieważ to co jest przesyłane do bazy i tak jest zakodowane w MD5. Nie mam kontroli nad hasłem bo może, a nawet powinno zawierać różne znaki.
mac_fly
Poczytaj o sql injection, a dowiesz się dlaczego powinno się filtrować wszystkie zmienne przychodzące.
!*!
fakt racja, przefiltruję to przy pierwszym sprawdzeniu, jednak czy jest sens przed wysłaniem tego do bazy skoro jest to md5?
siurek22
kolejny blad ;] przeslij sobie arraya i zobaczysz co ci wypluje smile.gif
Wicepsik
Cytat(mac_fly @ 13.07.2010, 15:02:51 ) *
Poczytaj o sql injection, a dowiesz się dlaczego powinno się filtrować wszystkie zmienne przychodzące.

Jeśli hasło będzie zakodowane w md5 to jaki jest sens filtracji ?
siurek22
nie wiem czy wiecie ale gdy przesle sie do md5() i wielu innych arraya zamiast danych to wypluwa nam ladne sciezki ktorych nieraz brakuje aby sie wlamac smile.gif
!*!
To czym i jak to przefiltrować? Przecież nie dam ograniczenia na znaki winksmiley.jpg sam mysql_real_escape_string wystarczy i md5? W innym wypadku całkowicie zmieni to hasło które poda użytkownik.
siurek22
na sam poczatek daj is_array() jezeli nie jest to daj md5 i styknie a jezeli bedzie to tablica to wiecie co z nia zrobic tongue.gif
!*!
Cytat(siurek22 @ 13.07.2010, 20:50:29 ) *
nie wiem czy wiecie ale gdy przesle sie do md5() i wielu innych arraya zamiast danych to wypluwa nam ladne sciezki ktorych nieraz brakuje aby sie wlamac smile.gif


Jakie ścieżki? Chodzi Ci o coś takiego?

Cytat
Warning: md5() expects parameter 1 to be string, array given in /var/www/index.php on line 22


To i tak jest niewidoczne w końcowej fazie udostępniania skryptu. Nikt przy zdrowych zmysłach nie zostawia tej opcji włączonej na serwerze.
siurek22
typowe podejscie informatyka lepiej wyciszyc niz wyeliminowac biggrin.gif http://gynvael.coldwind.pl/?id=246
!*!
Poprawiłem to według wskazówek.

  1. <?php
  2.  
  3. // zabezpieczenie danych odebranych z $_POST
  4. function zgp($danezget){return htmlspecialchars(strip_tags(trim(stripslashes($danezget))));}
  5. // zabezpieczenie danych wysyłanych do bazy
  6. function wds($zrodlo){return htmlspecialchars(mysql_real_escape_string(trim($zrodlo)));}
  7.  
  8. // odbieranie i sprawdzenie danych z formularza $_POST
  9. if (isset($_POST['signin'])){
  10.  
  11. if (isset($_POST['login']) && isset($_POST['password'])){ //sprawdzenie czy login i hasło zostało przesłane
  12.  
  13. $login = zgp($_POST['login']); //oczyszczenie funkcją
  14. $password = $_POST['password'];
  15.  
  16. //sprawdzanie loginu
  17. $loginnotallowed = array( 'admin', 'administrator', 'admini', 'root', 'reboot', 'poweroff', ' ');
  18. if(in_array($login, $loginnotallowed)) {$error=1;} //porównanie loginu z listy zablokowanej
  19. if (empty($login)) {$error=1;} //sprawdza czy pole jest puste
  20. if(!preg_match("/[a-z0-9_]/",$login)){$error=1;} // tylko małe litery i liczby oraz dolny myślink
  21. if(preg_match("/[A-Z]/",$login)){$error=1;} // błąd w przypadku wpisania dużych liter
  22. if(preg_match("/[\s\r\n]/",$login)){$error=1;} //błąd w przypadku użycia spacji
  23. if(is_array($login)){$error=1;unset($login);} //błąd w wypadku tablicy i usunięcie jej
  24.  
  25.  
  26. //sprawdzanie hasła
  27. if (empty($password)) {$error=1;} //sprawdza czy pole jest puste
  28. if(is_array($password)){$error=1;unset($password);} //błąd w wypadku tablicy i usunięcie jej
  29.  
  30. if ($error){echo 'Niepoprawny login lub hasło';}
  31.  
  32. if (!$error){// jeśli zadny z powyższych ifów nie zwrócił błedu $error = 1;
  33.  
  34. require_once('connect.php'); //połączenie z bazą
  35.  
  36. $login = wds($_POST['login']); //oczyszczenie funkcją wysyłającą do bazy
  37. $password = md5($_POST['password']); //kodowanie md5
  38.  
  39. $sprawdzlogin = mysql_query("SELECT id, login, password FROM userlogin WHERE login = '$login' AND password = '$password' LIMIT 1");
  40. $wyniksprawdz = mysql_num_rows($sprawdzlogin); //sprawdzanie loginu i hasła
  41.  
  42. if(!$wyniksprawdz){//sprawdzanie wynikiu odebranego z bazy
  43. $errordb=1; echo 'Niepoprawny login lub hasło';
  44. }
  45.  
  46. if(!$errordb){ // logowanie
  47. $_SESSION['logon'] = 1; //potwierdza poprawne zalogowanie
  48. $_SESSION['ip'] = $_SERVER['REMOTE_ADDR']; //umieszcza w sesji adres IP użytkownika
  49. $_SESSION['useragent'] = $_SERVER['HTTP_USER_AGENT']; //umieszcza w sesji useragenta użytkownika
  50. header('Location: http://'.DOMAIN_NAME.'/start');
  51. exit;
  52.  
  53. }
  54.  
  55.  
  56.  
  57. }
  58.  
  59. }
  60.  
  61. }
  62.  


Teraz jest dobrze? Macie jeszcze jakieś propozycje, sugestie odnośnie poprawienia bezpieczeństwa? Zdaję sobie sprawę że temat był wałkowany nie raz, jednak przy właśnie takim wałkowaniu można się czegoś nauczyć winksmiley.jpg
ps. czy któryś z moderatorów mógłby poprawić temat? U mnie wyskakuje komunikat że nie mogę tego zrobić przy zapisywaniu.
darko
Do komunikacji z bazą użyłbym PDO i zapytań preinterpretowanych . Oczywiście w formularzu ograniczasz maksymalną długość wpisywanego loginu i hasła, prawda?
  1. // powyższych
!*!
Tak, sprawdzam długość loginu i hasła nawet po stronie php, jednak zapomniałem je tu spowrotem wkleić przy edycji. PDO... próbuję podejść do tego któryś raz i nie za bardzo mi wychodzi, mam problem ze zrozumieniem wszystkiego co obiektowe.

Edycja:

Poprawka, hasło przesłane zaraz w formularzu nie może być obronione w md5, ponieważ po wpisaniu loginu jakiegokolwiek znaku, md5 nawet jak hasła nie ma, to zostanie połączenie do bazy i wysłanie odpowiedzi... Czyli hasło kodować w md5 tylko przy wysyłaniu do bazy? a co z odebraniem z formularza przy sprawdzaniu?
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.