URL SQL注入洞察力

时间:2018-12-27 11:37:33

标签: php mysql sql mysqli sql-injection

我有以下易受SQL注入影响的代码:

$r = $db->query(sanitizeSQL("SELECT a.* FROM asistentes a WHERE a.id = $id"));
f ($row = $r->fetchArray()) { 
    $scope['asistente'] = $row; 
    if (is_numeric($id) && $id != $_SESSION['auth']) { 
        $error = 'You don't have permission to see this user'; 
    } 
}else { 
    $error = 'Wrong assistant'; 
}

据我所知,该代码对SQL注入攻击很弱,因为尽管您使用过滤器sanitizeSQL清理了db-> query语句(我认为这是它们已编码的私有方法,而不是本机PHP过滤器) ,当您决定客户端是否将有权访问用户信息时,您使用的是客户端引入的$id值,而无需对其进行过滤或过滤,因此,可能的攻击者可以在此处引入任何SQL命令。 / p>

成功登录后获得的网址是:

10.14.79.2/?action=details&id=1

我尝试了一些方法来访问所需的用户,而一种可行的方法是这种方法:

10.14.79.2/?action=details&id=3;

只需添加要访问的用户ID和分号即可获得访问权限,而如果仅输入用户ID(不带分号),则会得到“您无权查看此用户”消息。

我想知道为什么该代码会那样。我的意思是:

  1. is_numeric是否会忽略分号并返回true,因为$id以数字开头吗?

  2. is_numeric($id) &&调用之后,如果$id调用正好在!=语句之前返回分号,则如何中断代码?我在代码的那部分没有分号的功能

  3. 分号如何跳过!=比较,以便我们获得向数据库询问的用户详细信息?

  4. 在此阶段是否有更好的方法来执行SQL注入?

2 个答案:

答案 0 :(得分:2)

  

is_numeric方法是否只是忽略分号并返回true,因为$ id以数字开头?

不。传递数字时,将检查该数字以查看其是否正确。如果不是数字,则第二次检查将永远不会执行。因此,操作如下:

  • 如果它是一个数字,而不是正确的数字,则会看到“您无权查看此用户”消息。
  • 如果它是一个数字并且是正确的数字,那么您不会看到“您无权查看此用户”消息
  • 如果不是数字,则看不到“您无权查看此用户”消息

PDFLinkService不是数字。这意味着最后一种情况适用,从不检查输入内容是否允许输入

  

在“ is_numeric($ id)&&”之后,如果$ id调用只是在!=语句之前返回分号,则$ id调用不会中断代码吗?我在代码的那部分没有分号的功能

如果$ id为3;,则表示它是字符串。如果要与3;进行比较,则将其作为字符串进行比较。它不会破坏代码。这一点并不重要,因为我们已经确定传递非数字的东西意味着永远不会检查它是否正确

  

分号如何跳过!=比较,以便我们获得向数据库询问的用户详细信息?

如果is_numeric()返回false,则从不执行!=比较。 $_SESSION['auth']不是数字。因此,is_numeric()返回false

  

在此阶段是否有更好的方法来执行SQL注入?

如果要注入,请在分号后放置一些SQL

答案 1 :(得分:1)

您最好先检查变量的有效性,然后再将其传递给查询。这样可以解决SQL注入的风险,并且还提供了一种更清晰的逻辑,您可以在其中将无效的ID与权限不足的用户区分开。

if (! is_numeric($id) ) {
    $error = 'You did not provide a valid id'; 
}
else {
    $r = $db->query(sanitizeSQL("SELECT a.* FROM asistentes a WHERE a.id = $id"));
    if ($row = $r->fetchArray()) { 
        $scope['asistente'] = $row;
        if ($id != $_SESSION['auth']) { 
            $error = 'You don't have permission to see this user'; 
        }
    }
}