1

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

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

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

4

6 回答 6

1

我会说最好寻找函数调用而不是寻找 SQL 本身。可能修改 PHP 解析器以查找导致运行 SQL 查询但不是准备好的查询的函数调用。

于 2008-08-21T19:28:46.357 回答
1

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

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

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

于 2008-08-21T16:49:51.760 回答
1

也许在针对BNF解析文本行时,比如SQL92,并根据片段与语法的匹配程度对每一行进行评分。

听起来像是一些繁重的工作。您的简单方法已经可以捕捉到如此大比例的真实案例。

于 2008-08-21T16:53:00.427 回答
1

我不知道 C# 中变量的细节,所以你将不得不原谅或否决我使用 PHP,但 70% 的时间我的 SQL 查询会进入这样的变量

$sql = "SELECT * FROM table;";

除此之外,我想不出你能做些什么来改进你已经拥有的东西。

您是否考虑在多行中创建的语句并在字符串中使用变量?(以下示例)

$sql = "SELECT * FROM table WHERE fname = $fname OR snmae = $sname";
于 2008-08-21T16:54:27.770 回答
0

I do not know the specifics of variables in C# so you will have to forgive or down-vote me for using PHP but 70% of the time my SQL query goes into a variable like so ..

Yeah, my original approach was to just look for the $sql vars since that is what most people use, but after testing against a few PHP apps I quickly threw that solution out because some developers use some funky variable names ...

Do you take into account statements that are created over several lines and use variables within the string? (Example below)

Yep. I also attempted to handle statements that were generated conditionally, but that didn't always work so well. ;)

于 2008-08-21T17:06:48.803 回答
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);
于 2008-08-21T17:28:59.030 回答