Php URL SQL注入洞察

Php URL SQL注入洞察,php,mysql,sql,mysqli,sql-injection,Php,Mysql,Sql,Mysqli,Sql Injection,我有以下代码: $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 h

我有以下代码:

$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(我认为这是他们编写的私有方法,而不是原生PHP过滤器)来清理db->query语句,但当您决定客户端是否将访问用户信息时,您使用的是客户端引入的
$id
值,但没有对其进行清理或过滤,因此可能的攻击者可以在那里引入任何SQL命令

成功登录时获得的url为:

10.14.79.2/?action=details&id=1
我尝试了一些方法来访问您想要的用户,一种有效的方法是:

10.14.79.2/?action=details&id=3;
只需添加要访问的用户id和分号,即可获得访问权限,而如果只输入用户id(不带分号),则会收到“您无权查看此用户”消息

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

  • is\u numeric
    方法是否因为
    $id
    以数字开头而忽略分号并返回true

  • 是数字($id)&&
    之后,如果
    $id
    调用在
    前面返回分号,它怎么不中断代码呢=语句?在代码的这一部分我没有分号的功能

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

  • 有没有更好的方法在这个阶段执行SQL注入

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

    否。当您传递一个号码时,会检查该号码是否正确。如果不是数字,则第二次检查从未执行过。因此,操作是:

    • 如果它是一个号码,但不是正确的号码,则您确实会看到“您没有查看此用户的权限”消息
    • 如果它是一个数字并且是正确的数字,则您不会看到“您没有查看此用户的权限”消息
    • 如果不是数字,则不会看到“您没有查看此用户的权限”消息
    3不是一个数字。这意味着最后一种情况适用,从未检查输入是否允许

    在“is_numeric($id)&&&”之后,如果$id调用返回的是一个分号,那么它如何不中断代码陈述在代码的这一部分我没有分号的功能

    如果$id为
    3这意味着它是一个字符串。如果要将它与
    $\u会话['auth']
    进行比较,它将作为字符串进行比较。它不会破坏密码。但这一点并不重要,因为我们已经确定传递非数字的内容意味着永远不会检查它是否正确

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

    那个!=如果is_numeric()返回false,则永远不会执行比较<编码>3不是一个数字。那么,是不是_numeric()返回false

    有没有更好的方法在这个阶段执行SQL注入


    如果要注入分号,请在分号后面加上一些SQL,最好在将变量传递到查询之前检查变量的有效性。这将修复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'; 
            }
        }
    }
    

    你的问题是
    3
    不是数字,因此与
    $\u会话['auth']
    的比较永远不会发生。而
    3
    在查询中是有效的(
    只是终止它),因此您确实会得到结果。“尽管您使用过滤器sanitizeSQL清理db查询”——这是毫无意义的定义。您不能在事后对查询进行“清理”。你需要在查询结构中正确地清理/转义/绑定单个值,在它已经成为查询的一部分并且注入已经发生之后,你不能这样做;根据定义,这仍然是不可能的。谢谢你的回答。看来,虽然3;不是一个数字,dm->query上的sanitizeSQL过滤器会清除分号,以便正确执行db请求,然后is_numeric()会像您所说的那样返回false。@Luiscri或后面的
    作为查询的一部分都非常好。这是一种更好的方式。但事实上,我试图实现的是利用SQL注入敏感系统的漏洞,而不是修复该漏洞哈哈,这是为了大学实践。谢谢你的回答