对于我的高级论文,我开发了一个程序,可以使用预准备语句自动检测并建议修复SQL注入漏洞。特别是PHP的mysqli扩展。我对SO社区的问题是:在PHP源代码中检测SQL的首选方法是什么?
我使用了一个包含SQL keywords (SELECT, INSERT, ...)
的枚举,基本上解析了每一行,迭代枚举以确定是否存在任何SQL。另外,我必须确保解析器没有错误地检测到html(例如< \ select>)。
对我来说,这个解决方案运行良好,但现在我现在有更多的时间在我的手上,并考虑重构代码以使用更优雅(和有效)的解决方案。请将您的解决方案限制为使用 C#,因为这是我编写程序的原因。
答案 0 :(得分:1)
您的解决方案对我来说似乎很好。另一种方法是使用PHP的语法用Lex / Yacc解析器解析PHP文件,有一个很好的C#语法解析工具,叫做Coco / R http://www.ssw.uni-linz.ac.at/coco/
但是我相信如果你解析语言,你最终会消耗太多时间(在开发和计算中)而没有额外的结果。
我会坚持你的机会主义方法,但是要针对各种PHP代码进行测试,并调整它以涵盖所有可能的情况。
答案 1 :(得分:1)
答案 2 :(得分:1)
我不知道C#中变量的具体情况,所以你不得不原谅我或者使用PHP投票,但是70%的时间我的SQL查询会变成这样的变量
$sql = "SELECT * FROM table;";
除此之外,我无法想到你可以做些什么来改善你已经拥有的东西。
您是否考虑了通过多行创建的语句并在字符串中使用变量? (以下示例)
$sql = "SELECT * FROM table WHERE fname = $fname OR snmae = $sname";
答案 3 :(得分:1)
我想说最好是寻找函数调用而不是寻找SQL本身。可能修改PHP解析器以查找导致运行SQL查询的函数调用,该查询不是准备好的查询。
答案 4 :(得分:0)
我不知道C#中变量的细节,所以你不得不原谅我或者使用PHP投票,但是70%的时间我的SQL查询会变成这样的变量。
是的,我最初的方法是只查找$ sql vars,因为这是人们使用的大多数,但在对几个PHP应用程序进行测试后,我很快就抛弃了该解决方案,因为一些开发人员使用一些时髦的变量名......
您是否考虑了通过多行创建的语句并在字符串中使用变量? (以下示例)
是的。我还尝试处理有条件生成的语句,但这并不总是很有效。 ;)
答案 5 :(得分:0)
一个简单的正则表达式,用于检测与函数一起使用的所有CRUD sql语句(假设$ script包含整个php脚本)
preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?\)\s*?;/is',
$script, $matches);
它应匹配所有可能的SELECT,INSERT,UPDATE,DELETE语句,如果它们放在括号和双引号内。这是个例子,并且应该匹配跨越多行的语句。
编辑#1:用于匹配CRUD语句的正则表达式,如字符串赋值;
preg_match_all('/\$\w+\s*?=\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?"\s*?;/is',
$script, $matches);
编辑#2:
// $variable detecting version of #1 regex
preg_match_all('/\(\s*?"(?:SELECT|INSERT|UPDATE|DELETE) .*?(?:\$\w+){1}.*?"\s*?\)\s*?;/is',
$script, $matches);