在PHP文件中解析SQL的最佳方法?

时间:2008-08-21 16:42:14

标签: c# .net php sql parsing

对于我的高级论文,我开发了一个程序,可以使用预准备语句自动检测并建议修复SQL注入漏洞。特别是PHP的mysqli扩展。我对SO社区的问题是:在PHP源代码中检测SQL的首选方法是什么?

我使用了一个包含SQL keywords (SELECT, INSERT, ...)的枚举,基本上解析了每一行,迭代枚举以确定是否存在任何SQL。另外,我必须确保解析器没有错误地检测到html(例如< \ select>)。

对我来说,这个解决方案运行良好,但现在我现在有更多的时间在我的手上,并考虑重构代码以使用更优雅(和有效)的解决方案。请将您的解决方案限制为使用 C#,因为这是我编写程序的原因。

6 个答案:

答案 0 :(得分:1)

您的解决方案对我来说似乎很好。另一种方法是使用PHP的语法用Lex / Yacc解析器解析PHP文件,有一个很好的C#语法解析工具,叫做Coco / R http://www.ssw.uni-linz.ac.at/coco/

但是我相信如果你解析语言,你最终会消耗太多时间(在开发和计算中)而没有额外的结果。

我会坚持你的机会主义方法,但是要针对各种PHP代码进行测试,并调整它以涵盖所有可能的情况。

答案 1 :(得分:1)

也许在对BNFSQL92解析文本行时会有一些问题,比如{{3}},并且每一行都会对片段与语法的匹配程度进行评分。

虽然听起来有点沉重。您的简单方法已经捕获了如此大比例的实际案例。

答案 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);