SQL - wtrysk

Jeśli wprowadzisz dane wejściowe użytkownika za pośrednictwem strony internetowej i wstawisz je do bazy danych SQL, istnieje szansa, że ​​pozostawiłeś się szeroko otwarty na problem bezpieczeństwa znany jako SQL Injection. W tym rozdziale dowiesz się, jak temu zapobiec i jak zabezpieczyć swoje skrypty i instrukcje SQL w skryptach po stronie serwera, takich jak skrypt PERL.

Wstrzyknięcie zwykle występuje, gdy poprosisz użytkownika o wprowadzenie danych, na przykład jego imię i nazwisko, a zamiast nazwy podają ci instrukcję SQL, którą nieświadomie uruchomisz w swojej bazie danych. Nigdy nie ufaj danym dostarczonym przez użytkownika, przetwarzaj te dane dopiero po weryfikacji; z reguły odbywa się to przezPattern Matching.

W poniższym przykładzie name jest ograniczona do znaków alfanumerycznych i podkreślenia oraz do długości od 8 do 20 znaków (zmodyfikuj te zasady w razie potrzeby).

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)) {
   $result = mysql_query("SELECT * FROM CUSTOMERS 
      WHERE name = $matches[0]");
} else {
   echo "user name not accepted";
}

Aby zademonstrować problem, rozważ ten fragment -

// supposed input
$name = "Qadir'; DELETE FROM CUSTOMERS;";
mysql_query("SELECT * FROM CUSTOMSRS WHERE name='{$name}'");

Wywołanie funkcji ma na celu pobranie rekordu z tabeli CUSTOMERS, w której kolumna name odpowiada nazwie określonej przez użytkownika. W normalnych okolicznościach,$namebędzie zawierać tylko znaki alfanumeryczne i być może spacje, takie jak ciąg ilia. Ale tutaj, dołączając zupełnie nowe zapytanie do $ name, wywołanie bazy danych zamienia się w katastrofę; wstrzyknięte zapytanie DELETE usuwa wszystkie rekordy z tabeli CUSTOMERS.

Na szczęście, jeśli używasz MySQL, rozszerzenie mysql_query()funkcja nie zezwala na zestawianie zapytań ani wykonywanie wielu zapytań SQL w jednym wywołaniu funkcji. Jeśli spróbujesz zestawić zapytania, wywołanie nie powiedzie się.

Jednak inne rozszerzenia baz danych PHP, takie jak SQLite i PostgreSQL szczęśliwie wykonuj zapytania skumulowane, wykonując wszystkie zapytania dostarczone w jednym ciągu i tworząc poważny problem z bezpieczeństwem.

Zapobieganie iniekcji SQL

Możesz inteligentnie obsługiwać wszystkie znaki ucieczki w językach skryptowych, takich jak PERL i PHP. Rozszerzenie MySQL dla PHP zapewnia tę funkcjęmysql_real_escape_string() aby uniknąć znaków wejściowych, które są specjalne dla MySQL.

if (get_magic_quotes_gpc()) {
   $name = stripslashes($name);
}
$name = mysql_real_escape_string($name);
mysql_query("SELECT * FROM CUSTOMERS WHERE name='{$name}'");

LIKE Quandary

Aby rozwiązać dylemat LIKE, niestandardowy mechanizm zmiany znaczenia musi konwertować dostarczone przez użytkownika znaki „%” i „_” na literały. Posługiwać sięaddcslashes(), funkcja, która pozwala określić zakres znaków do zmiany znaczenia.

$sub = addcslashes(mysql_real_escape_string("%str"), "%_");
// $sub == \%str\_
mysql_query("SELECT * FROM messages 
   WHERE subject LIKE '{$sub}%'");