Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP]walidacja danych
Forum PHP.pl > Forum > Przedszkole
phpuser88
Cześć, tworze system ankiet i przypadkiem zdałem sobie sprawę z względnie paskudnej luki, którą popełniłem w wielu miejscach...

Jeżeli chcemy dodać post, wpis lub cokolwiek innego to tworzymy formularz HTML <form>, a następnie odbieramy za pomocą PHP.
Teraz, jeżeli chcemy ograniczyć liczbę wpisów z danego formularza do wyłącznie jednego, to złym sposobem jest robienie tego za pomocą samego ukrycia/zlikwidowania/zablokowania formularza w HTML, bo daną treść można wstrzyknąć zdalnie... Wiem, że to pewnie dla większości z Was oczywistość, ale może ktoś nowy to przeczyta i będzie bardziej świadomy problemu, a ja chce tym wątkiem poruszyć temat możliwej obrony przed zdalnym wstrzykiwaniem danych do tego typu formularzy.

Jak się bronić przed kolejnym wstrzyknięciem treści?
Najprostszy i najskuteczniejszy sposób jaki przychodzi mi do głowy, to po walidacji danych, tuż przed wykonaniem INSERT'u do SQL należy zapytać baze czy nie ma wcześniejszego wpisu od danego ID, który chce dokonać kolejnego (zakazanego) wpisu.

Przykładowy kod poglądowy wygląda tak:
  1. if((!empty($_POST['tresc']) AND !empty($_POST['id']) AND $_POST['csrf']==$_SESSION['csrf']){
  2.  
  3. $id = (int)$_POST['id'];
  4. $tresc = walidacja($_POST['tresc']);
  5. $tresc = mysqli_real_escape_string($con,$tresc);
  6.  
  7. $INSERT = "INSERT INTO `przyklad` (`prosty`,`id`) VALUES ('$tresc','$id');";
  8.  
  9. $WymaganeSprawdzeniePrzedInsert = 'SELECT id FROM `przyklad` WHERE `id`='$id';';
  10.  
  11. if ($result = mysqli_query($con, $WymaganeSprawdzeniePrzedInsert)){
  12. if(!mysqli_num_rows($result)){
  13. mysqli_query($con, $INSERT);
  14. }
  15. }
  16. }


Teraz mam dwa pytania:
1. Czy mogę skutecznie określić lokalizację w PHP przy odbiorze danych, skąd dokładnie dane zostały wysłane (w sensie z jakiego pliku)? oraz czy będzie to wystarczające żeby ograniczyć wstrzykiwanie z zewnątrz? Jeżeli można to zapoda ktoś przykład?
2. Czy istnieje jeszcze jakiś dodatkowy sposób na pomocną walidację danych?
Tomplus
1. Waliduj z użyciem PDO:

  1. $stmt = $pdo->prepare('SELECT * FROM users WHERE email = :email AND status=:status');
  2. $stmt->execute(['email' => $email, 'status' => $status]);
  3. $user = $stmt->fetch();


Unikniesz SQL Injection, a wcześniej sprawdzać możesz dzięki takim funkcjom jak:

  1. filter_input(INPUT_POST, $email, FILTER_VALIDATE_EMAIL)


2. Wpisy do bazy danych nie muszą mieć inkrementacji ID w formie kolejnych numerów, użyj UUID dzięki temu, unikniesz możliwości powtórzenia tego samego ID, oraz ekstramalnie trudne będzie wyszukiwanie wpisów/kont użytkowników tylko po identyfikatorze liczbowym.
Szansa że wygeneruje się ten sam UUID to jak 1 do słońca w milimetrach.
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.