Предотвращение SQL-инъекций в Java-программе - PullRequest
12 голосов
/ 01 марта 2012

Мне нужно добавить инструкцию в Java-программу для обновления таблицы базы данных:

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

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

DROP TABLE customer; 

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

Ответы [ 8 ]

21 голосов
/ 01 марта 2012

Вам необходимо использовать 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();

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

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

13 голосов
/ 01 марта 2012

Я хочу знать, как хакер может добавить этот тип кода ("DROP TABLE customer;") в мой оператор вставки

Например:

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

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

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

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

7 голосов
/ 01 марта 2012

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

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

String selectStatement = "SELECT * FROM User WHERE userId = ? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();
5 голосов
/ 01 марта 2012

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

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

2 голосов
/ 01 марта 2012

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

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

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

1 голос
/ 08 ноября 2016

Как объяснено в этом посте , только 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:

1 голос
/ 18 ноября 2015

Go для PreparedStatement Преимущества PreparedStatement:

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

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

0 голосов
/ 02 ноября 2018

Несмотря на то, что все остальные ответы говорят вам о том, как вы можете исправить SQL-инъекции в Java, ответ Мукеша Кумара на самом деле говорит вам, кто на самом деле предотвращает подобные атаки.Поймите, что на самом деле его сервер БД, который предотвращает атаки SQL-инъекций, предоставил вам, как программисту, следовать их рекомендации по использованию параметризованных запросов.

См. Здесь - предотвращение уязвимостей SQL-инъекций

Java-программист не сможет очистить каждую входную строку, поэтому поставщики БД предоставили нам варианты подготовленныхЗаявления, и они говорят нам, чтобы подготовить и выполнить запросы, используя это и все остальное будет заботиться о поставщике БД.

Такие радикальные вещи, как DROP TABLE customer;, могут не произойти, но основная предпосылка внедрения SQL-кода заключается в том, что никто не должен иметь возможность разорвать ваш запрос, просто предоставив неверный ввод (преднамеренный или неумышленный).

OWASP - Шпаргалка по предотвращению инъекций SQL

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