防止java程序中的sql注入攻击

a1o7rhls  于 2021-08-25  发布在  Java
关注(0)|答案(9)|浏览(408)

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

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

我听说这可以通过sql注入加以利用,如:

DROP TABLE customer;

我的程序有一个JavaGUI,所有的名称、地址和电子邮件值都是从 Jtextfields . 我想知道下面的代码是怎么写的( DROP TABLE customer; )可能被黑客添加到我的insert语句中,以及我如何防止这种情况。

ep6jt1vc

ep6jt1vc1#

您需要使用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();

这将防止注射攻击。
黑客将其放入其中的方式是,如果您插入的字符串来自某个输入位置,例如网页上的输入字段,或应用程序或类似程序中表单上的输入字段。

lzfw57am

lzfw57am2#

我想知道这种代码(“drop table customer;”)是如何实现的可以被黑客添加到我的insert语句中
例如:

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

还要分析这些变量的值,确保它们不包含任何不允许的字符(例如“;”以某种名义)。

kcwpcxri

kcwpcxri3#

你可以查看这篇文章,了解这方面的信息!:)
我建议使用参数化查询:

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

ojsjcaue4#

攻击者只需输入以下内容 'foo@example.com"); DROP TABLE customer; 到田野里去 email 你就完了。
您可以通过对jdbc语句使用正确的转义来防止这种情况。

ss2ws0br

ss2ws0br5#

这就是为什么您应该在字符串语句中使用问号:

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

引自这里

hmtdttj4

hmtdttj46#

选择preparedstatement preparedstatement的优点:
sql语句的预编译和db端缓存导致总体执行速度加快,并且能够批量重用相同的sql语句。
通过引号和其他特殊字符的内置转义自动防止sql注入攻击。请注意,这需要使用任何preparedstatement set()方法来设置值

kqhtkvqz

kqhtkvqz7#

正如在这篇文章中所解释的那样 PreparedStatement 如果仍在连接字符串,则单独使用不会有帮助。
例如,一个恶意攻击者仍然可以执行以下操作:
调用sleep函数,使所有数据库连接都处于繁忙状态,从而使应用程序不可用
从数据库中提取敏感数据
绕过用户身份验证
这不仅仅是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:
jpa标准api
约克

ubby3x7f

ubby3x7f8#

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

yruzcnhs

yruzcnhs9#

尽管所有其他答案都告诉您如何修复java中的sql注入,但mukesh kumar的答案实际上告诉您是谁在实际阻止此类攻击。要知道,作为程序员,它的db服务器实际上是在防止sql注入攻击,只要您遵循他们使用参数化查询的建议。
请参阅此处-防止sql注入漏洞
java程序员不可能清理每个输入字符串,所以db供应商给了我们准备语句的选项,他们告诉我们使用这些语句准备和执行查询&其余的事情将由db供应商处理。
像这样激烈的事情 DROP TABLE customer; 可能不会发生,但sql注入的基本前提是,任何人都不能仅仅通过提供无效输入(有意或无意)来破坏您的查询。
owasp-sql注入预防备忘单

相关问题