防止Java程序中的SQL注入攻击

时间:2012-03-01 12:56:34

标签: java mysql sql sql-injection

我必须在我的java程序中添加一个语句来更新数据库表:

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

我听说这可以通过SQL注入来利用,如:

DROP TABLE customer; 

我的程序有一个Java GUI,所有名称,地址和电子邮件值都是从Jtextfields检索的。我想知道黑客如何将以下代码(DROP TABLE customer;)添加到我的插入语句中,以及如何防止这种情况。

9 个答案:

答案 0 :(得分:21)

您需要使用PreparedStatement。 e.g。

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

这可以防止注射攻击。

黑客把它放在那里的方式是你插入的字符串来自某处的输入 - 例如网页上的输入字段,或应用程序中的表单上的输入字段等。

答案 1 :(得分:13)

  

我想知道这段代码(“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);

同时解析您对这些变量的值,并确保它们不包含任何不允许的字符(例如名称中的“;”)。

答案 2 :(得分:7)

您可以查看THIS文章了解相关信息! :)

我推荐参数化查询:

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

答案 3 :(得分:5)

攻击者必须在'foo@example.com"); DROP TABLE customer;的字段中输入email之类的内容,您就完成了。

您可以通过使用正确的JDBC语句转义来防止这种情况。

答案 4 :(得分:2)

这就是你应该在字符串语句中使用问号的原因:

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

引自here

答案 5 :(得分:1)

转到PreparedStatement PreparedStatement的优点:

SQL语句的预编译和数据库端缓存可以提高整体执行速度,并能够批量重用相同的SQL语句。

通过内置转义引号和其他特殊字符来自动防止SQL注入攻击。请注意,这要求您使用任何PreparedStatement setXxx()方法来设置值

答案 6 :(得分:1)

this post中所述,如果您仍在连接字符串,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:

答案 7 :(得分:0)

尽管所有其他答案都告诉您如何用Java修复SQL注入,但是Mukesh Kumar的答案实际上告诉您是谁在实际上阻止了这类攻击。请理解,作为程序员,您实际使用的DB服务器可以防止SQL注入攻击,因此请遵循其使用参数化查询的建议。

Refer Here - Preventing SQL Injection Vulnerabilities

Java程序员不可能清理每个输入字符串,因此DB供应商已经为我们提供了Prepared Statements选项,他们告诉我们通过使用Prepared Statements准备和执行查询,其余的事情将得到处理。由数据库供应商提供。

可能不会发生像DROP TABLE customer;这样剧烈的事情,但是SQL注入的基本前提是没有人能够通过仅提供无效输入(有意或无意)破坏查询。

OWASP - SQL Injection Prevention Cheat Sheet

答案 8 :(得分:0)

还应该尽可能严格地限制访问数据库的帐户的特权。例如,对于搜索,该帐户只需要对所需的那些表和列具有读取权限。这样可以防止破坏性的SQL注入并限制对敏感数据的访问。