2009-10-13 14 views
5

Historycznie, zawsze stosowanyCzy PHP MySQLi przygotowane zapytania z zabezpieczonymi parametrami są bezpieczne?

mysql_real_escape_string() 

dla wszystkich wejściowych pochodzących od użytkowników, że kończy się dotykając bazy danych.

Teraz, gdy całkowicie przełączyłem się na MySQLi i używam przygotowanych zapytań o powiązanych parametrach, czy skutecznie wyeliminowałem możliwość ataków typu SQL injection?

mam rację, mówiąc, że nie trzeba już

mysql_real_escape_string()? 

To jest moje zrozumienie i podstawą projektu kopalni: http://sourceforge.net/projects/mysqldoneright/files/Base/MysqlDoneRight-0.23.tar.gz/download

To nie jest coś, co chcę dostać źle chociaż jako teraz, gdy go wydałem, może to również wpłynąć na innych.

Wszystkie dane wprowadzone przez użytkownika będą teraz wyświetlane jako bind_parms.
Kwerendy podane w fazie przygotowania są statyczne.

Odpowiedz

6

To nie jest takie proste. Można użyć parametrów oprawionych zamiast interpolacji zmiennych aplikacji do wyrażenia SQL zamiast wartości dosłownych tylko:

$sql = "SELECT * FROM MyTable WHERE id = ".$_GET["id"]; // not safe 

$sql = "SELECT * FROM MyTable WHERE id = ?"; // safe 

Ale co, jeśli trzeba wykonać część zapytania dynamiczny oprócz wartości dosłownym?

$sql = "SELECT * FROM MyTable ORDER BY ".$_GET["sortcolumn"]; // not safe 

$sql = "SELECT * FROM MyTable ORDER BY ?"; // doesn't work! 

Parametr będzie zawsze interpretowany jako wartość, a nie jako identyfikator kolumny. Możesz uruchomić zapytanie o numerze ORDER BY 'score', które różni się od ORDER BY score, a użycie parametru będzie interpretowane jako poprzednie - ciąg stały 'score', a nie wartość w kolumnie o nazwie score.

Tak więc istnieje wiele przypadków, w których trzeba użyć dynamicznego SQL i interpolować zmienne aplikacji do zapytania, aby uzyskać pożądane wyniki. W takich przypadkach parametry zapytania nie pomogą. Nadal musisz być czujny i kodować defensywnie, aby zapobiec wadom wstrzyknięcia SQL.

Żadna biblioteka ramowa ani biblioteka dostępu do danych nie mogą wykonać tej pracy za Ciebie. Zawsze można skonstruować ciąg zapytania SQL, który zawiera lukę w iniekcji SQL, i robisz to, zanim biblioteka dostępu do danych zobaczy zapytanie SQL. Więc jak to jest wiedzieć, co jest zamierzone, a co wadą?

Oto sposoby osiągnięcia bezpiecznych zapytań SQL: wejście

  • filtra. Śledzenie wszelkich danych zmiennych, które zostaną wstawione do zapytań SQL. Użyj wejścia filters, aby usunąć niedozwolone znaki.Na przykład, jeśli oczekujesz liczby całkowitej, upewnij się, że wejście jest ograniczone do liczby całkowitej.

  • Wyjście awaryjne. Dane wyjściowe w tym kontekście mogą być kwerendami SQL wysyłanymi do serwera bazy danych. Wiesz, że możesz używać parametrów zapytania SQL dla wartości, ale co z nazwą kolumny? Potrzebujesz identyfikatora dla funkcji escaping/quoting, tak jak stara mysql_real_escape_string() jest dla wartości łańcuchowych.

  • Recenzje kodów. Poszukaj kogoś, kto będzie drugą parą oczu i przejrzyj kod SQL, aby pomóc Ci rozpoznać miejsca, w których zaniedbałeś korzystanie z powyższych dwóch technik.

+0

Tak. Zauważyłeś, że nie możesz wykonać ORDER BY? bit z parametrami. Dobra odpowiedź. –

+0

Mam awans? Downvoter, powinieneś opisać, dlaczego uważasz, że ta odpowiedź nie jest satysfakcjonująca. Być może mogę to poprawić. –

13

Tak. Użycie przygotowanego zapytania spowoduje uniknięcie parametrów.

+0

Krótkie, słodkie i dokładne. – ceejayoz

+0

Dzięki. Chciałem tylko upewnić się, że nie brakuje mi czegoś oczywistego. Zwykle to robię. –

1

Po powiązaniu parametrów z przygotowaną instrukcją, dane są automatycznie wymywane, więc nie należy przed tym uciekać przed wysłaniem. Podwójne ucieczki są zwykle złe. Co najmniej, przynosi on brzydkie wyniki z późniejszymi postaciami, które uciekły.