我意识到参数化SQL查询是构建包含用户输入的查询时消毒用户输入的最佳方式,但我想知道使用用户输入并转义任何单引号并用单引号包围整个字符串有什么问题.这是代码:
sSanitizedInput = "'" & Replace(sInput, "'", "''") & "'"
Run Code Online (Sandbox Code Playgroud)
用户输入的任何单引号都被双单引号替换,这消除了用户结束字符串的能力,因此他们可能键入的任何其他内容(例如分号,百分号等)都将成为字符串的一部分而不是实际上作为命令的一部分执行.我们使用的是Microsoft SQL Server 2000,我相信单引号是唯一的字符串分隔符,也是逃避字符串分隔符的唯一方法,因此无法执行用户键入的任何内容.
我没有看到任何方法发起针对此的SQL注入攻击,但我意识到,如果这是像我看来一样的防弹,其他人会想到它,这将是常见的做法.我的问题是:这段代码有什么问题?有没有人知道通过这种清理技术获得SQL注入攻击的方法?利用此技术的示例用户输入将非常有用.
更新:
感谢大家的回答; 几乎我在研究中遇到的所有信息都出现在这个页面的某个地方,这表明那些在忙碌的日子里抽出时间帮助我解决这个问题的人的智慧和技巧.
我还没有接受任何答案的原因是我仍然不知道如何有效地针对此代码启动SQL注入攻击.有些人建议反斜杠会转义一个单引号而另一个引用字符串结束,以便字符串的其余部分作为SQL命令的一部分执行,我意识到这个方法可以将SQL注入一个mySQL数据库,但在MS SQL 2000中,唯一的方法(我能够找到)逃避单引号是另一个单一的qoute; 反斜杠不会这样做.除非有办法停止单引号的转义,否则其余的用户输入都不会被执行,因为它将全部作为一个连续的字符串.
我知道有更好的方法来消毒输入,但我真的更有兴趣了解为什么我上面提供的方法不起作用.如果有人知道对这种清理方法进行SQL注入攻击的任何特定方法,我很乐意看到它.
为了开始这个,我很清楚参数化查询是最好的选择,但我想知道是什么让我在下面提出的策略容易受到攻击.人们坚持认为下面的解决方案不起作用,所以我找一个为什么它不会这样做的例子.
如果在发送到SQL Server之前使用以下转义在代码中构建动态SQL,那么什么样的注入可以打败这个?
string userInput= "N'" + userInput.Replace("'", "''") + "'"
Run Code Online (Sandbox Code Playgroud)
在SQL Server中无法使用"\"转义单引号.
我相信使用Unicode进行SQL走私(此处概述)会被生成的字符串被单引号前面的N标记为Unicode这一事实所阻碍.据我所知,SQL Server没有其他字符集会自动转换为单引号.没有未转义的单引号,我不相信注射是可能的.
我不相信String Truncation也是一个可行的载体.SQL Server肯定不会截断,因为根据microsoft,a的最大大小为nvarchar2GB .在大多数情况下,2 GB的字符串是不可行的,在我的情况下是不可能的.
二阶注入是可能的,但如果可能的话:
我并不是说这比使用参数化查询更好或者替代,但我想知道我概述的内容是如何易受攻击的.有任何想法吗?
我有一个特殊情况,要求我从用户提供的输入值生成SQL WHERE子句的一部分.我想防止任何类型的SQL注入漏洞.我想出了以下代码:
private String encodeSafeSqlStrForPostgresSQL(String str) {
//Replace all apostrophes with double apostrophes
String safeStr = str.replace("'", "''");
//Replace all backslashes with double backslashes
safeStr = safeStr.replace("\\", "\\\\");
//Replace all non-alphanumeric and punctuation characters (per ASCII only)
safeStr = safeStr.replaceAll("[^\\p{Alnum}\\p{Punct}]", "");
//Use PostgreSQL's special escape string modifier
safeStr = "E'" + safeStr + "'";
return safeStr;
}
Run Code Online (Sandbox Code Playgroud)
问题:
笔记:
这是关于SO和其他地方的常见问题,但我看到的唯一答案是始终使用PreparedStatements.Fwiw,我正在使用JasperReports.我想将查询保留在JasperReports中.用于查询参数处理的内置Jasper参数函数(包括X {}函数)不足以满足我的参数化需求.我可以尝试创建一个自定义的Jasper QueryExecutor,它允许我注入我自己的X {}函数,但这比使用Jasper的$ P!{}语法生成动态SQL where子句更复杂.
我查看了OWASP库.他们还没有PostgresSQL编解码器.我查看了OracleCodec,它的转移似乎过于简单.我不确定这对防止SQL注入攻击有多大帮助.
在我的代码中,我添加了E,以便不依赖于PostgreSQL的standard_conforming_strings设置.理想情况下,我不必添加它,然后该函数不必是PostgreSQL特定的.更多信息:http://www.postgresql.org/docs/9.0/static/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE. …