故事是这样的。我正在测试一个以MySQL数据库为主要数据存储库的Laravel (PHP框架)应用程序的安全性测试(使用zaproxy)。
Zaproxy为POST请求URL报告了一个可能的SQL注入,其有效负载如下:
id[]=3-2&enabled[]=on基本上,它是一个AJAX请求,用于打开/关闭列表中的特定功能。Zaproxy正在对请求进行模糊处理:在id值为3-2的地方,应该有一个整数--要更新的项的id。
问题是,这一要求是可行的。它应该会失败,但是代码实际上是在更新id = 3所在的项。
我正在按照我应该做的方式来做:模型是使用雄辩的Model::find($id)方法检索的,从请求中传入id值(经过一番调查,该值被确定为字符串"3-2")。AFAIK,雄辩的库应该通过将ID值绑定到参数来执行查询。
我尝试使用Laravel的DB类执行查询,代码如下:
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3-2"));给id = 3排了一行。
然后,我尝试对我的MySQL数据库执行以下查询:
SELECT * FROM table WHERE id='3-2';确实检索了id = 3所在的行。我也尝试了另一个价值:"3abc“。它看起来像,任何以数字为前缀的值都会检索一行。
因此,最终,这似乎是MySQL的一个问题。就我而言,如果我请求一个行,其中没有一个具有确切ID值的行,那么我希望它返回一个空的结果集。
我有两个问题:
发布于 2015-05-05 20:31:49
SELECT * FROM table WHERE id= ? AND ? REGEXP "^[0-9]$";这将比我在上面的评论中建议的要快。编辑:啊,我看你不能改变这个查询。然后确认,您必须清除代码中的输入。另一个非常糟糕而又脏的选项是将id字段更改为VARCHAR,如果您在一个奇怪的情况下无法更改查询,但可以更改数据库。
发布于 2015-05-05 20:34:46
我相信这是由于MySQL在与数字数据类型进行比较时自动将字符串转换为数字。
https://dev.mysql.com/doc/refman/5.1/en/type-conversion.html
mysql>选择SELECT 1> '6x'; -> %0 mysql>选择SELECT 7> '6x'; -> 1 mysql>选择0> 'x6'; -> %0 mysql>选择0= 'x6'; -> 1
你真的想把盔甲放在MySQL周围,以防止这样的字符串被比较。可能切换到另一个SQL服务器。
发布于 2015-05-05 21:19:30
如果不重写一堆代码,那么诚实地说,正确的答案是
这不是一个问题。
Zaproxy甚至声称它是,可能是注入攻击,这意味着它不知道!它从来没有说过“嗯,我们把x-y-和-z传递给您的查询,从而删除了表”。
// if this is legal and returns results
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3"));
// then why is it an issue for this
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3-2"));
// to be interpreted as
$result = DB::select("SELECT * FROM table WHERE id=?;", array("3"));您正在参数化您的查询,所以Zaproxy是不正确的--它是摇滚乐。
https://stackoverflow.com/questions/30062587
复制相似问题