我应该如何清理Java中的数据库输入?

时间:2009-03-26 22:25:24

标签: java mysql security sql-injection

有人可以指点我一个关于安全运行部分来自用户输入的SQL查询的初学者指南吗?我正在使用Java,但语言中立的指南也很好。

理想的行为是,如果有人在GUI中键入类似

的内容

very nice;) DROP TABLE FOO;

数据库应将其视为文字字符串并安全地存储它而不删除任何表。

5 个答案:

答案 0 :(得分:10)

您肯定想使用PreparedStatement。他们很方便。这是一个example

答案 1 :(得分:7)

答案 2 :(得分:5)

通常,您不应创建连接输入的查询,而应使用PreparedStatement

这使您可以指定在查询中设置参数的位置,因此Java将负责为您清理所有输入。

答案 3 :(得分:3)

的PreparedStatement?是的,一点没错。但我认为还有一个步骤:验证来自UI的输入以及在接近数据库之前绑定到对象。

我可以看到在PreparedStatement中绑定String的位置可能仍然容易受到SQL注入攻击:

String userInput = "Bob; DELETE FROM FOO";
String query = "SELECT * FROM FOO WHERE NAME = ?";

PreparedStatement ps = connection.prepareStatement(query);
ps.setString(1, userInput);
ps.executeQuery();

我必须承认我自己没有尝试过,但如果这是远程可能的话,我会说PreparedStatement是必要的,但还不够。在服务器端验证和绑定是关键。

我建议使用Spring的绑定API。

答案 4 :(得分:3)

您的用户输入实际上必须是"Bob'; delete from foo; select '"(或类似的东西),因此准备好的语句添加的隐式引号将被关闭:

SELECT * FROM FOO WHERE NAME = 'Bob'; delete from foo; select ''

但如果您这样做,准备好的语句代码将引用您的引用,以便您获得

的实际查询
SELECT * FROM FOO WHERE NAME = 'Bob''; delete from foo; select '''

,您的姓名将存储为"Bob', delete from foo; select '",而不是运行多个查询。