2009-03-26 14 views
13

Czy ktoś mógłby wskazać mi dobry podręcznik dla początkujących na temat bezpiecznego uruchamiania zapytań SQL utworzonych częściowo na podstawie danych wprowadzonych przez użytkownika? Używam Java, ale przewodnik neutralny językowo też jest w porządku.Jak należy odłożyć dane wejściowe bazy danych w Javie?

pożądane zachowanie jest, że jeśli ktoś wpisze do czegoś GUI jak

very nice;) DROP TABLE FOO;

Baza powinna traktować je jako ciąg dosłownym i przechowywać je bezpiecznie bez pomijania żadnych tabel.

Odpowiedz

5

Zazwyczaj nie powinna utworzyć kwerendę łącząc wejście, ale używając PreparedStatement zamiast.

Dzięki temu możesz określić, w których miejscach będziesz ustawiać parametry w zapytaniu, tak aby Java zadbała o higienę wszystkich danych wejściowych.

3

PreparedStatement? Tak, absolutnie. Ale myślę, że jest jeszcze jeden krok: sprawdzanie poprawności danych wejściowych z interfejsu użytkownika i wiązanie obiektów przed zbliżeniem się do bazy danych.

widzę gdzie wiązanie String w PreparedStatement może nadal zostawiają cię podatne na atak SQL injection:

String userInput = "Bob; DELETE FROM FOO"; 
String query = "SELECT * FROM FOO WHERE NAME = ?"; 

PreparedStatement ps = connection.prepareStatement(query); 
ps.setString(1, userInput); 
ps.executeQuery(); 

Muszę przyznać, że nie próbował go samodzielnie, ale jeśli to jest zdalnie możliwe, że powiedziałbym, że PreparedStatement jest konieczny, ale niewystarczający. Sprawdzanie poprawności i wiązanie po stronie serwera jest kluczowe.

Zalecam zrobienie tego przy użyciu wiążącego API Spring.

+0

To jest dokładnie ten rodzaj ataku, którego zadaniem jest przygotowanie przygotowanych oświadczeń. Ucieknie przed;. – danieltalsky

+0

Technicznie interfejs PreparedStatement nie gwarantuje tego. Chociaż jeśli twój kierowca robi coś innego, znajdź nowego dostawcę. –

+0

@daniel - Będę musiał spróbować i przekonać się. Czy mam rację, czy nie, czy nie zgadzasz się, że walidacja po stronie serwera nadal jest dobrym pomysłem? – duffymo

3

Twój wkład użytkownik może faktycznie być "Bob'; delete from foo; select '" (czy coś takiego), więc ukryte cytaty dodane przez przygotowanym oświadczeniu będzie zamknięta:

SELECT * FROM FOO WHERE NAME = 'Bob'; delete from foo; select '' 

ale jeśli nie, że przygotowany kod oświadczenie będzie zacytować Twój cytat więc masz rzeczywistą kwerendy

SELECT * FROM FOO WHERE NAME = 'Bob''; delete from foo; select ''' 

oraz imię i nazwisko zostanie zapisane jako "Bob', delete from foo; select '" zamiast uruchamiania wielu zapytań.

Powiązane problemy