Php 修补基于时间的sql注入
我最近在客户机上执行了一次代码审计,我发现这些代码行接受了盲SQL注入 代码段:Php 修补基于时间的sql注入,php,mysql,sql,security,Php,Mysql,Sql,Security,我最近在客户机上执行了一次代码审计,我发现这些代码行接受了盲SQL注入 代码段: <?php if ($_GET['id'] != ''){ $groepsindeling = $_GET['id']; } else { $groepsindeling = $_GET['group']; } breadcrumb($groepsindeling); ?> <?php $groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '
<?php
if ($_GET['id'] != ''){
$groepsindeling = $_GET['id'];
} else {
$groepsindeling = $_GET['group'];
}
breadcrumb($groepsindeling);
?>
<?php
$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC";
$groepres = mysql_query($groep);
while ($groeprij = mysql_fetch_array($groepres)){
?>
如上所述,在您的查询中使用$_GET['id'],这意味着人们仍然可以通过SQL注入查询字符串:
$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC";
试着做:
$groep = "SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '{$groepsindeling}' ORDER BY `naamt1` ASC";
然后使用“$groepsindeling”变量,在该变量上使用real\u escape\u字符串
您还应该阅读-正如它所说,当您使用“mysqli_real_escape_string”时,您还需要在方法中设置mysqli对象:
string mysqli_real_escape_string ( mysqli $link , string $escapestr )
另外,您应该使用MySQLi或MySQL(不推荐使用这种) 正如其他人所指出的,查询中仍然有转义的$\u GET['id']
,但是严格地说,$groepsindeling
可能与GET var不等价。基本上你说的是
$groepsindeling = $_GET['id'] or $_GET['group'];
此处代表:
if ($_GET['id'] != ''){
$groepsindeling = $_GET['id'];
} else {
$groepsindeling = $_GET['group'];
}
这不是原始查询中表示的内容
"SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$_GET[id]' ORDER BY `naamt1` ASC";
该查询严格使用了$\u GET['id']
,因为我在那里没有看到$\u GET['group']
。那么剩下两个选择,
- 原始代码有缺陷
- 原始代码是正确的(在这种情况下,$Id应该是一个新变量)
就这样
$id = mysqli_real_escape_string($_GET['id']);
"SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$id' ORDER BY `naamt1` ASC";
如果看不到此页面的全部代码,就无法判断该$groepsindeling
是否与查询相关,或者只是在其他地方使用。我提到的另一种可能性是,它们是相同的,并且原始代码被窃听
综上所述,考虑到面包屑($groepsindeling)代码>我认为它与查询无关,并保持代码不变。更改它并在查询中包含$\u GET['group']
值可能会导致不可预测的行为,特别是如果该查询依赖$\u GET['id']=''
进行任何操作
有道理
作为补充说明,在当前的PHP版本中,从原始查询中获取[id]
可能会抛出一个未定义常量
警告,我以前在5.3之前的PHP代码中见过这种用法。。。。它应该是$\u GET['id']
。它仍然有效,因为PHP将为未定义的常量提供其名称的字符串表示形式。(这只是一种判断代码有多旧的方法:-p)
最后一个注意事项是,您正在使用
mysql\u query
和mysqli\u real\u escape\u string
以使其中的i
具有某种意义,或者说在mysql\u query
中缺少它。mysql.*
函数已被弃用,如果我记得从PHP7起已被删除,这意味着此代码在PHP5x之后不会成为未来的证明。我不确定mysql\u real\u escape\u string
和mysqli\u real\u escape\u string
在查询中是否仍使用未转义的$\u GET['id')。1。您正在混合使用mysql和mysli API。2.您不应该再使用mysql api了。它早就被弃用了,并在PHPV7中被删除。3.对于所有类型的sql注入,简单的转义是不够的。要么使用参数化查询(在mysql api中不可用,仅在mysqli或pdo中可用),要么必须增强转义代码。@CapitalC但我仍然可以在查询中使用该函数吗?@Shadow某些客户端不想更改其代码;(@Shadow是的,我知道mysql api已被弃用,但他们不想更改代码。这就是我被困在这里的原因。需要找到一种方法来修补此问题,而不需要对代码进行大量更改。我已经建议使用WAF(web应用程序防火墙),但他们当然谢绝了。非常感谢,现在问题已经解决了!感谢您的帮助!!@epidrollic-原始代码有缺陷,您意识到了吗?在原始代码中`$\u GET['group'];`从未在查询中使用。通过更新,您正在将其放入查询中,这可能不是最初的目的。换句话说,假设$groepsindeling
=$\u GET[id]
不正确。应使用新变量。
$id = mysqli_real_escape_string($_GET['id']);
"SELECT * FROM `menubalk` WHERE `webnr` LIKE '%$webnr-%' AND `hoofdgroep` = '$id' ORDER BY `naamt1` ASC";