如果我没有在Java / J2EE中使用“PreparedStatement”的选项,如何防止SQL注入

时间:2011-04-11 15:38:25

标签: sql-injection

我有一个应用程序我无法在某些地方使用“PreparedStatement”。

大多数SQL查询都像......。 String sql =“delete from”+ tableName;

所以我想知道如何在我的代码中修复“SQL注入”问题。

此致 桑杰辛格

=======================编辑得到答案后想要验证解决方案========== 根据提供的建议,我已经确定了一种在我的情况下防止SQL注入的策略.... 想知道观点,我正在为我们的应用程序开发VeraCode证书......

过滤数据,因此它不会占用任何空间并转义SQL字符(因此,如果有任何注入的代码,  它不会成为我的动态SQL的一部分,因此我的列名和表名不能用于注入SQL查询。)

public static String getTabColName(String tabColName)
    {
    if(tabColName == null ||“”。。equals(tabColName.trim()))
                 返回“”;
    String tempStr = StringEscapeUtils.escapeSql(tabColName.trim());
    //如果此值内容空间表示它不是有效表
    //或列名,所以不要在动态生成的SQL中使用它     //使用空格,以便创建无效的SQL查询     return tempStr.indexOf('')== -1? tempStr:“”;
    }

3 个答案:

答案 0 :(得分:1)

如果您没有经过同行评审的字符串转义函数库,那么至少应该列出您知道可以安全嵌入字符串的白名单字符。例如,确保您的字符串仅由字母,数字和下划线组成,而不是其他内容。黑名单已知的“坏人物”有望让你陷入困境。

答案 1 :(得分:1)

参数化查询是防止SQL注入攻击的重要一步。如果你不能使用它们,你手中也会遇到同样重大的挫折。您可以稍微通过以下方式减轻危险:

  • 输入字符串验证。我的意思是验证所有的花里胡哨,有时可以达到一个完整的解析器的水平,而不仅仅是一些检查。

  • 输入操作(例如引用和字符串转义)。同样,你必须做到这一点,这可能比看起来更难。

这两种技术都存在问题 - 您必须通过未更改进行有效输入,以保持与当前代码库的兼容性,同时仍然有效地保护您的系统。祝你好运...

根据我的经验,重构 - 甚至重写 - 使用预准备语句的代码将为您节省大量时间和眼泪。

答案 2 :(得分:1)

确保输入仅包含允许的字符只是重要的第一步。您的示例语句是策略值的一个很好的示例“在所有正常值列表中查找输入”(您肯定知道数据库中的表集以及允许用户使用表的子集)。 “将输入与合理范围进行比较”(薪水不应增加数百万或半美分),或“匹配正则表达式以显示结构违规”是进一步的例子。

为了对你的防御有信心,你可以考虑使用类似QuickCheck的测试库来通过(适当偏见的)随机字符串攻击你的验证函数。这个article列出了除Haskell之外的语言的实现。