有时,SQL Inject查询可能是通过使用您习惯的不同字符集来伪装的。但即使在那些伪装模式中,查询字符串仍然会包含熟悉的单词,例如union,cast和varchar等。
我的问题是这个;
是否有可能甚至伪装这些词?换句话说,“联合”或“演员”也可以伪装吗?
答案 0 :(得分:6)
SQL标准要求关键字使用拉丁字符A到Z或a到z,数字0到9以及特定的特殊字符。请参阅“SQL-99 Complete,Really”中的SQL Language Elements。
也就是说,个别实现(例如Oracle,Microsoft SQL Server,MySQL)可能不完全符合标准。最好的方法是测试您使用的RDBMS的品牌和版本。
重新评论:MySQL允许将/* */
个评论嵌入到关键字中,但在其他品牌的数据库中,内联评论或多或少与空白一样。
因此SEL/* */ECT
与SEL ECT
类似,当然这不是有效的关键字,因此会失败。
我认为注释分隔符也必须是ascii范围内的字符,但我没有对此进行测试以确定。根据实施情况,它可能因RDBMS的品牌而异。所以答案必须考虑到这一点(提示:你还没有告诉我们你正在使用什么类型的数据库)。
另一种“伪装”可能是URL编码。也就是说,对单个字符使用HTML实体或HTML十六进制编码。 SQL无法识别这些,但如果您在解码之前过滤原始输入,则某些内容可能会超出您的检查范围。
最终,我的最佳做法政策是:
永远不要让用户输入作为代码运行(这也适用于从文件甚至从数据库本身读取的任何不受信任的内容)。使用参数化或至少是可靠的转义函数,而不是直接将内容插入到SQL字符串中。
如果您希望根据用户输入制作SQL动态的其他部分,则参数化无效。例如,让用户选择如何对结果进行排序:
SELECT * FROM MyTable ORDER BY $ColumnOfUsersChoice $AscVsDesc
在这种情况下,我的做法是使用白名单,因此我们将用户输入与一组固定的有效选项进行比较,而不是尝试使用与正则表达式匹配的模式。白名单的优点是,如果恶意用户尝试任何聪明的东西,他们的输入将被忽略。
有关白名单的示例,请参阅我的演示文稿SQL Injection Myths and Fallacies或我的图书SQL Antipatterns: Avoiding the Pitfalls of Database Programming。
这是我录制SQL注入神话和谬误的视频录像:http://marakana.com/forums/web_dev/general/210.html但是我继续改进幻灯片,因为视频制作完成,所以会有一些差异。
答案 1 :(得分:5)
SQL注入不需要包含任何关键字。
例如,
DELETE FROM Table WHERE ID=<<<Injected Payload>>>
将使用不包含字母数字字符的注入有效内容执行更多操作:
''||''=''
答案 2 :(得分:5)
您正在从错误的方向接近问题。防止SQL注入的唯一可靠方法是确保数据永远不会作为代码执行,通过解析或正确转义它。
使用参数化查询将帮助您进行转义,因为这样做很难处理。
在输入中查找关键字仅作为辅助措施,以保护完全没有任何保护的严重编写的代码。