Предотвращение атак 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 (), чтобы задать значение