Как я должен дезинфицировать базу данных ввода в Java? - PullRequest
13 голосов
/ 27 марта 2009

Может ли кто-нибудь указать мне хорошее руководство для начинающих по безопасному запуску SQL-запросов, сформированных частично из пользовательского ввода? Я использую Java, но не зависит от языка.

Желаемое поведение заключается в том, что если кто-то набирает в GUI что-то вроде

very nice;) DROP TABLE FOO;

База данных должна обрабатывать ее как буквальную строку и хранить ее безопасно, не удаляя таблицы.

Ответы [ 5 ]

10 голосов
/ 27 марта 2009

Вы определенно хотите использовать PreparedStatement s. Они удобны. Вот пример .

7 голосов
/ 27 марта 2009

Использовать PreparedStatement вместо Заявление

5 голосов
/ 27 марта 2009

Как правило, вы не должны создавать входные данные, объединяющие запросы, а вместо этого использовать PreparedStatement .

Это позволяет вам указать, в каких местах вы будете устанавливать свои параметры в запросе, поэтому Java позаботится о том, чтобы очистить все входные данные для вас.

3 голосов
/ 03 апреля 2009

Ваш пользовательский ввод на самом деле должен быть "Bob'; delete from foo; select '" (или что-то в этом роде), поэтому неявные кавычки, добавленные подготовленным оператором, будут закрыты:

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

но если вы сделаете это, подготовленный код выписки процитирует вашу цитату, и вы получите фактический запрос

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

и ваше имя будет сохранено как "Bob', delete from foo; select '" вместо выполнения нескольких запросов.

3 голосов
/ 27 марта 2009

PreparedStatement? Да, конечно. Но я думаю, что есть еще один шаг: проверка ввода от пользовательского интерфейса и привязка к объектам перед приближением к базе данных.

Я вижу, где связывание строки в PreparedStatement может по-прежнему делать вас уязвимыми для атаки SQL-инъекцией:

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

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

Я должен признать, что сам не пробовал, но если это возможно удаленно, я бы сказал, что PreparedStatement необходим, но не достаточен. Проверка и привязка на стороне сервера является ключевым.

Я бы порекомендовал сделать это с помощью API привязки Spring.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...