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

防止Java程序中的SQL注入攻击,java,mysql,sql,sql-injection,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检索的。我想知道黑客如何将以下

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

String insert =
    "INSERT INTO customer(name,address,email) VALUES('" + name + "','" + addre + "','" + email + "');";
我听说这可以通过SQL注入加以利用,如:

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

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

我建议使用参数化查询:

String selectStatement = "SELECT * FROM User WHERE userId = ? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();
你需要使用。 e、 g

这将防止注射攻击


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

攻击者只需输入类似于
的内容即可foo@example.com"); 投递台客户进入
电子邮件
字段,您就完成了


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

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

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

我想知道这种代码(“DROP TABLE customer;”)是如何实现的 被黑客添加到我的insert语句中

例如:

name = "'); DROP TABLE customer; --"
将在insert中产生该值:

我特别想知道怎样才能防止这种情况发生

使用准备好的语句和SQL参数(Matt Fellows提供的示例“被盗”):

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

转到PreparedStatement 编制报表的优点:

SQL语句的预编译和DB端缓存导致总体执行速度加快,并且能够批量重用相同的SQL语句

通过引号和其他特殊字符的内置转义自动防止SQL注入攻击。请注意,这要求您使用任何PreparedStatement setXxx()方法来设置值,如中所述,
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:


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

Java程序员不可能清理每个输入字符串,所以DB供应商给了我们准备语句的选项,他们告诉我们使用这些语句准备和执行查询&其余的事情将由DB供应商处理

像<代码>丢表客户这样激烈的事情可能不会发生,但SQL注入的基本前提是,任何人都不能仅仅通过提供无效输入(有意或无意)来破坏您的查询


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

我使用的GUI可能重复。个人只能通过文本字段输入值。他们怎么能把这样的代码添加到我的状态中呢。像这样插入客户(姓名、地址、电子邮件)值(“”);投递台客户--“、”、“+addre+”、“+email+”);为什么不输入“);删除表客户;--在文本字段中?无论如何,恶意用户可以破解这些文本字段限制(例如,直接修改RAM、注入伪造的网络包等).我不想自己重写它:D@m0skit0一个理想的攻击向量可以是一个受限系统,在那里用户将不具有管理员权限,甚至逃避到主操作系统。拥有一个带有SQL注入可能性和键盘输入的文本框,可以允许窃取凭据和其他信息。n存储在DB中。如何编辑咖啡店客户计算机中的RAM?即使可以,难道不能从程序配置中获取身份验证凭据并对服务器造成严重破坏吗?这确实可以在一定程度上防止SQL注入攻击,因为它将代码与数据分离。下面是一个简短的教程,介绍
INSERT INTO customer(name,address,email)     VALUES(''); DROP TABLE customer; --"','"+addre+"','"+email+"');
String insert = "INSERT INTO customer(name,address,email) VALUES(?, ?, ?);";
PreparedStament ps = connection.prepareStatment(insert);
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();