Предотвращать атаки 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();

Это предотвратит атаки инъекций.

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


Я хочу знать, как этот кусок кода ( "DROP TABLE customer" ) может быть добавлен в мою инструкцию insert хакером

Например:

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

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

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

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

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

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();


Нападающему просто нужно ввести что-то вроде '[removed_email]"); DROP TABLE customer; в поле для email, и все готово.

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


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

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

цитируется здесь


Как объяснено в этот пост, только 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() для установки значения

licensed under cc by-sa 3.0 with attribution.