poniedziałek, 24 września 2018

SQLite - bezpieczeństwo danych


SQLite - Injection

Jeśli otrzymasz dane wprowadzane przez użytkownika na stronie www i wstawisz je do bazy danych SQLite, istnieje szansa, że ​​się szeroko otworzysz na problemy związane z bezpieczeństwem, znane jako SQL Injection. W tym rozdziale dowiesz się, jak temu zapobiec i zabezpieczyć skrypty i instrukcje SQLite.
Injection zazwyczaj pojawia się, gdy pytasz użytkownika o dane wejściowe, takie jak jego imię, a zamiast nazwy podaje instrukcję SQLite, którą nieświadomie uruchomisz w bazie danych.
Nigdy nie ufaj danym dostarczonym przez użytkownika, przetwarzaj te dane tylko po zatwierdzeniu, z reguły odbywa się to poprzez dopasowanie do wzorca. W poniższym przykładzie nazwa użytkownika jest ograniczona do znaków alfanumerycznych plus podkreślenia i do długości od 8 do 20 znaków - w razie potrzeby zmodyfikuj te reguły.
if (preg_match("/^\w{8,20}$/", $_GET['nazwa_użytkownika'], $matches)){
   $db = new SQLiteDatabase('nazwa_pliku');
   $result = @$db->query("SELECT * FROM uzytkownik WHERE nazwa_uzytkownika = $matches[0]");
} else {
   echo "nie zaakceptowano nazwy użytkownika";
}
Aby zademonstrować problem, rozważ ten fragment -
$nazwa = "Ryszard'; DELETE FROM uzytkownik;";
@$db->query("SELECT * FROM uzytkownik WHERE nazwa_uzytkownika = '{$nazwa}'");
Wywołanie funkcji ma na celu pobranie rekordu z tabeli użytkowników, w którym nazwa kolumny odpowiada nazwie określonej przez użytkownika. W normalnych okolicznościach $nazwa zawierałaby jedynie znaki alfanumeryczne i być może spacje, takie jak łańcuch znaków ilia. Jednak w tym przypadku, poprzez dodanie całkowicie nowego zapytania do $nazwa, wywołanie bazy danych staje się katastrofą,  wstrzyknięte zapytanie DELETE usuwa wszystkie rekordy z tabeli uzytkownik.
Istnieją interfejsy baz danych, które nie pozwalają na układanie zapytań lub wykonywanie wielu zapytań w jednym wywołaniu funkcji. Jeśli spróbujesz zapytać o stos, połączenie nie powiedzie się, ale SQLite i PostgreSQL, z radością wykonują połączone zapytania, wykonują wszystkie zapytania zawarte w jednym ciągu i stwarzają poważny problem bezpieczeństwa.

Zapobieganie iniekcji SQL

Możesz obsłużyć wszystkie znaki specjalne w językach skryptowych, takich jak PERL i PHP. Język programowania PHP udostępnia funkcję string sqlite_escape_string(), która pozwala uniknąć znaków wejściowych, które są specyficzne dla SQLite.
if (get_magic_quotes_gpc()) {
   $nazwa = sqlite_escape_string($nazwa);
}
$result = @$db->query("SELECT * FROM users WHERE username = '{$nazwa}'");
Chociaż kodowanie umożliwia bezpieczne wstawianie danych, spowoduje, że proste porównania tekstu i klauzule LIKE w zapytaniach będą nieużyteczne dla kolumn zawierających dane binarne.
Uwaga - addslashes() nie powinny być wykorzystywane między znakami cytowania w ciągach tekstowych kwerend SQLite, doprowadzi to do dziwnych rezultatów podczas pobierania danych.




Brak komentarzy:

Prześlij komentarz