我有一个应用程序我无法在某些地方使用“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:“”;
}
答案 0 :(得分:1)
如果您没有经过同行评审的字符串转义函数库,那么至少应该列出您知道可以安全嵌入字符串的白名单字符。例如,确保您的字符串仅由字母,数字和下划线组成,而不是其他内容。黑名单已知的“坏人物”有望让你陷入困境。
答案 1 :(得分:1)
参数化查询是防止SQL注入攻击的重要一步。如果你不能使用它们,你手中也会遇到同样重大的挫折。您可以稍微通过以下方式减轻危险:
输入字符串验证。我的意思是验证所有的花里胡哨,有时可以达到一个完整的解析器的水平,而不仅仅是一些检查。
输入操作(例如引用和字符串转义)。同样,你必须做到这一点,这可能比看起来更难。
这两种技术都存在问题 - 您必须通过未更改进行有效输入,以保持与当前代码库的兼容性,同时仍然有效地保护您的系统。祝你好运...
根据我的经验,重构 - 甚至重写 - 使用预准备语句的代码将为您节省大量时间和眼泪。
答案 2 :(得分:1)
确保输入仅包含允许的字符只是重要的第一步。您的示例语句是策略值的一个很好的示例“在所有正常值列表中查找输入”(您肯定知道数据库中的表集以及允许用户使用表的子集)。 “将输入与合理范围进行比较”(薪水不应增加数百万或半美分),或“匹配正则表达式以显示结构违规”是进一步的例子。
为了对你的防御有信心,你可以考虑使用类似QuickCheck的测试库来通过(适当偏见的)随机字符串攻击你的验证函数。这个article列出了除Haskell之外的语言的实现。