SQLite - wtrysk

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

Wstrzyknięcie zwykle ma miejsce, gdy poprosisz użytkownika o wprowadzenie danych, na przykład jego imię i nazwisko, a zamiast nazwy podają ci instrukcję SQLite, 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 poprzez dopasowywanie wzorców. W poniższym przykładzie nazwa użytkownika jest ograniczona do znaków alfanumerycznych i podkreślenia oraz do długości od 8 do 20 znaków - zmodyfikuj te reguły w razie potrzeby.

if (preg_match("/^\w{8,20}$/", $_GET['username'], $matches)){ $db = new SQLiteDatabase('filename');
   $result = @$db->query("SELECT * FROM users WHERE username = $matches[0]");
} else {
   echo "username not accepted";
}

Aby zademonstrować problem, rozważ ten fragment -

$name = "Qadir'; DELETE FROM users;";
@$db->query("SELECT * FROM users WHERE username = '{$name}'");

Wywołanie funkcji ma na celu pobranie rekordu z tabeli użytkowników, w którym kolumna nazwy 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. Jednak w tym przypadku, poprzez dołączenie całkowicie nowego zapytania do $ name, wywołanie bazy danych zamienia się w katastrofę: wstrzyknięte zapytanie DELETE usuwa wszystkie rekordy od użytkowników.

Istnieją interfejsy baz danych, które nie pozwalają na zestawianie zapytań ani wykonywanie wielu zapytań w jednym wywołaniu funkcji. Jeśli spróbujesz zestawić zapytania, wywołanie kończy się niepowodzeniem, ale SQLite i PostgreSQL z radością 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. Funkcję zapewnia język programowania PHPstring sqlite_escape_string() aby uniknąć znaków wejściowych, które są specjalne dla SQLite.

if (get_magic_quotes_gpc()) {
   $name = sqlite_escape_string($name);
}
$result = @$db->query("SELECT * FROM users WHERE username = '{$name}'");

Chociaż kodowanie zapewnia bezpieczne wstawianie danych, będzie renderować proste porównania tekstu i LIKE klauzule w zapytaniach nie nadają się do użytku w kolumnach zawierających dane binarne.

Note - addslashes()NIE należy używać do cytowania swoich ciągów w zapytaniach SQLite; będzie to prowadzić do dziwnych rezultatów podczas pobierania danych.