Предотвращение атак SQL-инъекций в Java-программе

Я должен добавить оператор в мою программу java для обновления таблицы базы данных:

String insert =
    "INSERT INTO customer(name,address,email) VALUES('" + name + "','" + addre + "','" + email + "');";

Я слышал, что это можно использовать через SQL-инъекцию, например:

DROP TABLE customer; 

моя программа имеет графический интерфейс Java, и все значения имени, адреса и электронной почты извлекаются из Jtextfields. Я хочу знать, как следующий код (DROP TABLE customer;) может быть добавлен в мою инструкцию insert хакером и как я могу предотвратить это.

7 ответов


вам нужно использовать PreparedStatement. например,

String insert = "INSERT INTO customer(name,address,email) VALUES(?, ?, ?);";
PreparedStatement ps = connection.prepareStatement(insert);
ps.setString(1, name);
ps.setString(2, addre);
ps.setString(3, email);

ResultSet rs = ps.executeQuery();

Это позволит предотвратить атаки.

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


Я хочу знать, как этот вид кусок кода ("клиент таблицы падения;") может добавьте к моей инструкции insert хакера

например:

name = "'); DROP TABLE customer; --"

даст это значение в вставить:

INSERT INTO customer(name,address,email)     VALUES(''); DROP TABLE customer; --"','"+addre+"','"+email+"');

Я особенно хочу знать, как я могу предотвратить это

используйте подготовленные операторы и аргументы SQL (пример "украден" у Мэтта Феллоуза):

String insert = "INSERT INTO customer(name,address,email) VALUES(?, ?, ?);";
PreparedStament ps = connection.prepareStatment(insert);

также разобрать значения таких переменных и убедитесь, что они не содержат недопустимых символов (например,"; " в имени).


вы можете проверить этой статья для информации об этом! :)

Я рекомендую параметризованные запросы:

String selectStatement = "SELECT * FROM User WHERE userId = ? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();

злоумышленник просто должен ввести что-то вроде 'foo@example.com"); DROP TABLE customer; в поле email и вы сделали.

вы можете предотвратить это, используя правильное экранирование для операторов JDBC.


вот почему вы должны использовать вопросительные знаки в строке заявления:

 PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES
                                     SET SALARY = ? WHERE ID = ?");
   pstmt.setBigDecimal(1, 153833.00)
   pstmt.setInt(2, 110592)

цитата из здесь


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

например, один злоумышленник-изгоев все еще может сделать следующее:

и это не просто SQL, но JPQL и HQL могут быть скомпрометированы, если вы не используете параметры привязки:

PreparedStatement ps = connection.prepareStatement(
    INSERT INTO customer(name,address,email) VALUES(?, ?, ?)
);
int index = 0;
ps.setString(++index, name);
ps.setString(++index, address);
ps.setString(++index, email);

ResultSet rs = ps.executeQuery();

в нижней строке вы никогда не должны использовать конкатенацию строк при создании операторов SQL. Используйте выделенный API для этой цели:


перейти к PreparedStatement Преимущества PreparedStatement:

предварительная компиляция и кэширование на стороне БД инструкции SQL приводит к общему более быстрому выполнению и возможности повторного использования той же инструкции SQL в пакетах.

автоматическое предотвращение атак SQL-инъекций путем встроенного экранирования кавычек и других специальных символов. Обратите внимание, что для этого необходимо использовать любой из методов PreparedStatement setXxx (), чтобы задать значение