Php 修补基于时间的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 '

我最近在客户机上执行了一次代码审计,我发现这些代码行接受了盲SQL注入

代码段:

<?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";