坏代码:为什么这很危险?

时间:2010-07-16 13:39:45

标签: java sql security sql-injection

  

可能重复:
  Can I protect against SQL Injection by escaping single-quote and surrounding user input with single-quotes?

     String badInput = rawInput.replace("'","''");
     ResultSet rs = statement.executeQuery("SELECT * FROM records WHERE col1 = '"+badInput+"'";

有没有办法对这段代码进行“Bobby Tables”攻击?

8 个答案:

答案 0 :(得分:10)

根据所有必须解释命令的方式的不同步骤,可能有一些可能传递%27(例如)并使其作为单引号,通过您的替换而不被注意。

但即使可以涵盖所有这些案例,而且这个单一问题实际上是安全的,但缺乏这一点,因为它不能一致地实施。其他人可能会出现并希望添加AND int1 = var1,并注意到您已经考虑过SQL注入,因此他们只是以您的确切方式修改代码

String badInput = rawInput.replace("'","''");
String badInteger = rawInteger.replace("'","''");
ResultSet rs = statement.executeQuery("SELECT * FROM records WHERE" +
 "int1 = " + badInteger + " OR col1 = '"+badInput+"'");

...只有整数,它不再是你要保护自己的引用!在这里,很明显看到任何事情都可能出错。因此,虽然这是一个需要有人实施它的问题,但我认为这是设计中最大的问题 - 它只涵盖了一小部分案例。

能够简单地说“以下是变量。无论它包含什么,将其视为值,并且不要尝试将其中的一部分用作代码并执行该代码。”

答案 1 :(得分:4)

在MySQL中,如果未设置NO_BACKSLASH_ESCAPES选项,我相信可以这样做。

\'); DROP 

或类似的东西。您的代码将加倍'。第一个'将被反斜杠转义,第二个将关闭允许SQL注入的字符串。

我通常更愿意坚持准备好的陈述以保证安全。

答案 2 :(得分:3)

我最近向准备声明介绍了我的兄弟。在他当前的项目中实施了它,他找到了

  • 他可以摆脱所有乱糟糟的逃脱
  • 他可以摆脱所有混乱的字符串连接
  • 他的代码运行得更快。

为什么的人会使用准备?

答案 3 :(得分:2)

您可以尝试:

badInput = "\\'; drop records; --";

如果您的转义字符恰好设置为'\'

答案 4 :(得分:2)

也许。取决于replace方法实际上做了什么,特别是遇到unicode代理对或组合标记时 - 以及类似的数据库访问技术如何处理这些对。如果replace在char级别工作,那么如果攻击者为您提供有效的高代理,后跟单引号字符,您可能会用一对单引号替换该单引号 - 实际上,附加在一些东西之后的单引号 - 可能 - 稍后通过编码并被解释为无效的代理对,留下一个裸的单引号字符。

可能。

你对代码和数据库连接另一端的SQL执行引擎之间的替换方法和每个插入字符串处理库的unicode特性有足够的了解吗?

你感觉幸运吗?

使用参数化查询。

答案 5 :(得分:0)

我不是安全专家但不会char()有效地绕过您的安全措施?

例如:从记录表中获取所有内容

SELECT * FROM records WHERE col1 = char(39,97,39)

例如2:将信息写入没有单引号的文件

SELECT * FROM records WHERE col1 = concat(char(39),char(97),char(100),char(109),char(105),char(110),char( 39)) into outfile concat(char(39),char(97),char(100),char(109),char(105),char(110),char( 39))

来源:SQL Injection Cheat Sheet

答案 6 :(得分:0)

因为只有一个黑客才能发明一种绕过'替代品的方式,而这种方式是我们今天无法想到的。 (访问数据库的其中一个层中的一个小错误???)

答案 7 :(得分:0)

这很容易并且总是引发注射攻击。