SQL_INJECTION_JDBC 从文件加载时查找错误

SQL_INJECTION_JDBC Findbugs when loading from file

我有一个匿名过程,我使用 StatementLoader 获取该过程并将其传递给 CallableStatement。然而,FindBugs 将此标识为易受 SQL 注入 (SQL_INJECTION_JDBC) 攻击。如果我创建一个静态方法 returns 作为字符串的过程就没问题。

有没有一种方法可以在不弹出 sql 注入错误的情况下使用语句加载器?

示例:

StatementLoader stmt = StatementLoader.getLoader(MyClass.class, connection);    
try (final CallableStatement callable = connection.prepareCall(stmt.load("mySqlCode"))) {...

是的,如果您的程序只是从外部源加载 SQL 语句并执行它,它 真正的 SQL 注入机会. SQL 语句在程序中应该是常量,在执行时使用参数替换来提供值。 bug-catcher 是正确的——你应该立即重写这段代码。

我想明确我所说的"parameters,"是什么意思,因为OP的最新评论使用了"sanitized."

这个词

SQL 允许在 SQL 语句中使用 "parameters" – 由 而非 文字字符串的问号表示 –例如:

SELECT * FROM CUSTOMER WHERE CUSTOMER_ID = ?

每次执行语句时,都必须为每个参数提供一个值,通常是一个值数组。 (当然,大多数实际的数据库API都比较友好,让你方便"name"你的参数。)所以,参数从来不是[=的一部分52=] 字符串.

SQL 语句仅被解析 ("prepared") 一次,数据库引擎知道每次执行该语句时都必须提供参数值。查询引擎将直接获取并使用这些参数值;它不会重新评估 SQL。 (顺便说一句,效率明显更高!)

您提供的 binary 值按原样使用。您甚至不必将它们转换为字符形式。具体来说,不要"sanitize"他们!如果您在 INSERT 语句中向某些字符类型的列提供诸如 FOO%20BAR 的值,您会发现一个 9 字符文字值被插入到您的数据库:F-O-O-%-2-0-B-A-R。 "Those are the 9 characters that you gave me, so that's what I did."

(数据库系统及其接口在处理数据类型方面有所不同,例如 "date.")