我必须在我的java程序中添加一个语句来更新数据库表:
String insert =
"INSERT INTO customer(name,address,email) VALUES('" + name + "','" + addre + "','" + email + "');";
我听说这可以通过SQL注入来利用,如:
DROP TABLE customer;
我的程序有一个Java GUI,所有名称,地址和电子邮件值都是从Jtextfields
检索的。我想知道黑客如何将以下代码(DROP TABLE customer;
)添加到我的插入语句中,以及如何防止这种情况。
答案 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注入的基本前提是没有人能够通过仅提供无效输入(有意或无意)破坏查询。
答案 8 :(得分:0)
还应该尽可能严格地限制访问数据库的帐户的特权。例如,对于搜索,该帐户只需要对所需的那些表和列具有读取权限。这样可以防止破坏性的SQL注入并限制对敏感数据的访问。