使用预准备语句进行SQL注入?

时间:2009-03-24 17:26:29

标签: sql sql-injection prepared-statement

如果我没记错的话,我认为Jeff在Stack Overflow播客中提到了SQL预处理语句中可能存在的弱点。我想知道他所指的是哪种弱点?它可能只是inappropriate usage,还是更险恶的东西?

对于我的记忆而言,播客没有更深入地探讨这个主题,这只是一个传记。

4 个答案:

答案 0 :(得分:6)

我认为他说的是,当你使用Prepared Statements时,SQL服务器可以缓存你的查询执行计划,所以,即使你修改执行查询的一些参数,服务器也可能选错了(可能是缓存的) )执行计划表现非常糟糕。

他还提到了SQL Server 2008的一个新功能,迫使引擎重新评估他用来克服这种情况的执行计划。

有了准备好的陈述,我唯一的问题是这个。请考虑以下Java代码:

String sql = "select * from table where name like ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "PATTERN%");
ResultSet rs = pstmt.executeQuery();

在这里,您可以预期,如果您在表(名称)上有索引,它将由查询计划使用。好吧,它不会。因为PraparedStatement必须预先编译并预期最坏的情况:'%PATTERN%',例如。所以,它不会优化。我花了一段时间才想出这个。这导致我的数据库受损。 :(

希望它有所帮助。

答案 1 :(得分:2)

除了正常的sql注入(我们可能称之为第一顺序)攻击之外还有次要级别。例如,让存储过程使用字符串连接来构建然后执行的查询并不罕见。如果检索到的字段值的结果包含在这样的串联中,则存在注入的危险。

答案 2 :(得分:1)

如果准备的语句具有以任何方式动态构造的参数,那么这很可能是弱点的来源。

如果你使用一个带有测试类的正确数据库来设置参数,那么你就不会在任何时候打开自己的SQL注入,准备好是否使用。

请记住,仅仅因为准备了一个语句,或者因为您正在使用存储过程,这并不意味着您不会受到注入攻击。只有当您使用数据库提供程序代码清理参数输入(以及将其应用于可以使用的所有参数)时,才能获得SQL注入保护。

答案 3 :(得分:0)

我没有收听过该播客,但根据我的经验,只有预先准备好的声明。它通常会提高应用程序的性能并防止SQL注入(如果使用正确,而不是链接中的第二个示例)。