Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]SQL Injection i przerobienie skryptu
Forum PHP.pl > Forum > Przedszkole
Dukov
Hejka, spotkałem się ostatnio z nieprzyjemną sytuacją i straciłem calutką bazę danych, już to w zasadzie naprawiłem, tylko mam pewien problem, ktoś ma pomysł jak przerobić ten skrypt, żeby znów działał?
  1. function checkExists($login,$mail){
  2.  
  3. try{
  4. $conn = new PDO("mysql:host=localhost;dbname=wojtecki", 'root', '');
  5. $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  6. $stmt = $conn->prepare("SELECT count(*) FROM users WHERE login = ':login'");
  7. $stmt->execute(array(':login' => $login));
  8. $row = $stmt->fetch();
  9. $result = $row[0];
  10.  
  11. $check;
  12.  
  13. if($result <> 1){
  14.  
  15. $check = true;
  16.  
  17. }
  18. else
  19. {
  20. return 0;
  21. }
  22. $stmt = $conn->prepare("SELECT count(*) FROM users WHERE mail =':mail'");
  23. $stmt->execute(array(':mail' => $mail));
  24. $row = $stmt->fetch();
  25. $result = $row[0];
  26.  
  27. if($result <> 1){
  28.  
  29. $check = true;
  30.  
  31. }
  32. else
  33. {
  34. return 0;
  35. }
  36.  
  37. if ($check == true) {
  38. return 1;
  39. }
  40. $conn = null;
  41.  
  42.  
  43. }
  44. catch(PDOException $e){
  45. $e ->getMessage();
  46. echo $e;
  47. }
  48.  
  49.  
  50. }


Wcześniej sprawdzal czy istnieje już taki mail albo login w bazie i zwracał zero, jeśli znalazł użytkownika, jeśli do zmiennej check dodawał 1 i ją zwracał. Teraz oczywiście nie działa.
Zmieniłem tylko te dwie linijki
  1. $stmt = $conn->prepare("SELECT count(*) FROM users WHERE login = ':login'");
  2. $stmt->execute(array(':login' => $login));


Oczywiście w sprawdzeniu maila też takie dwie linijki zmieniłem.
nospor
O, doskonaly przyklad jak konczy sie ignorowanie tego co tu piszemy. Z tego co pamietam to juz ci mowiono bys zaczal uzywac bindowania.

Co do problemu to nie
login = ':login'

a:
login = :login

Jestem pewien, ze w manualu php w przykladach, wyraznie to jest widac...
Dukov
Już się zorientowałem. Że :login wink.gif Nieco się ździwiłem gdy zobaczyłem w bazie :login i :password wink.gif

EDIT Wszystko działa dzięki wink.gif W zasadzie ustawiłem sobie wczoraj ddns, nie trwało to 10 sek, jak bazy nie miałem.
viking
A wiesz że w zapytaniu można używać OR?
Dukov
Wiem, ale co to ma do rzeczy? Zapytania się dublują, to masz na myśli? Nie mogę dać OR, bo jeśli login jest prawdą, to nie sprawdzi czy mail też jest ok, poza tym ta funkcja jest delikatnie zmodyfikowaną funkcją logowania, w które można się logować albo mailem albo loginem. Stąd dwa warunki Choć mógłbym to w sumie zanegować albo jeszcze inaczej rozwiązać. Tak czy tak widzisz, ze skryptu na skrypt i tak jest jakiś postęp, coraz lepiej to idzie, na pewno może za 5 skryptem będe to robił jeszcze inaczej, dowiem się nowych rzeczy, napiszę kilka innych nabiorę doświadczenia i zrobię to lepiej. Tak jak już zawsze będę korzystał z bindowania zmiennych z post i get.

BTW to co teraz robię, to jest zupełnie coś innego, to o co kiedyś tutaj pytałem, to były 3 inne rzeczy i już dawno wylądowały w koszu, choć pewne wnioski z nich wyciągnąłem, już mam trochę dosyć tego, ale mam nadzieję, choć to doprowadzić do końca. Tak czy tak spoko, ze skrypty na skrypt będzie coraz lepiej wink.gif
viking
Twój skrypt w takiej postaci i tak zwróci bzdury czyli 1 dla nieprawidłowych danych. Najpierw popraw bazę żeby dane były unikalne.

"Nie mogę dać OR, bo jeśli login jest prawdą, to nie sprawdzi czy mail też jest ok...w które można się logować albo mailem albo loginem." Coś sobie przeczysz.

  1. function checkExists(string $login = null, string $mail = null) : int {
  2.  
  3. try{
  4. $conn = new PDO("mysql:host=localhost;dbname=test", 'root', '');
  5. $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  6. $stmt = $conn->prepare("SELECT count(*) AS num FROM users WHERE login = :login OR email = :email LIMIT 1");
  7. $stmt->execute(array(':login' => $login, ':email' => $mail));
  8. $row = $stmt->fetch(PDO::FETCH_ASSOC);
  9. return (int) $row['num'];
  10. }
  11. catch(PDOException $e){
  12. return 0;
  13. }
  14. }


Możesz też stworzyć zapytanie w stylu:
  1. SELECT sum(c) num FROM (
  2. (SELECT count(*) AS c FROM users WHERE login = :login)
  3. UNION
  4. (SELECT count(*) AS c FROM users WHERE mail = :mail)
  5. ) t
mmmmmmm
Cytat(viking @ 8.08.2017, 16:34:23 ) *
  1. SELECT sum(c) num FROM (
  2. (SELECT count(*) AS c FROM users WHERE login = :login)
  3. UNION
  4. (SELECT count(*) AS c FROM users WHERE mail = :mail)
  5. ) t

Bym był twoim pracodawcą i zobaczył taki kod, to byś się pakował. (albo przynajmniej porządna zjeba)
  1. SELECT ... FROM users WHERE :login/mail IN (login, mail)
viking
Podaj pełne zapytanie i porównamy jakie problemy rozwiązują oba.
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.