6

可能重复:
mysql_real_escape_string() 做了什么,而addslashes() 没有?

我一直在查看有关 PHP 的 addlashes 函数如何/为什么容易受到 sql 注入攻击的文章。我读过的所有内容都说特定的mysql编码类型(默认字符集=GBK)存在问题,或者如果启用了magic_quotes,则会出现问题。但是,在这种情况下,我无法突破 addlashes() 函数并做一些恶意的事情——比如以管理员身份登录。

    $user = addslashes($_POST['user']);
    $pass = sha1($_POST['pass']);
    $sql = "SELECT * FROM admins WHERE user = '".$user."' AND `pass` = '".$pass."'";

    $nums = mysql_num_rows(mysql_query($sql));

    if($nums==1){
    $_SESSION['admin_user'] = $user;
    $_SESSION['admin_pass'] = $pass;

这是针对客户的(次要)安全审计,我建议他们使用 PDO,但我需要显示他们当前的漏洞。

参考:

4

4 回答 4

3

Shiflett 在他的博客文章中展示了一个完整的工作漏洞。您在上面显示的代码似乎没有遵循该示例,因为它没有使用显示漏洞的字符集。不过,这个洞肯定是存在的。

即使它在特定场景中碰巧是安全的,但使用实践addslashes()仍然是危险的,Shiflett 的文章应该为您提供足够的材料来争论,即使漏洞利用所需的环境非常深奥,而且它们并非完全微不足道复制。

如果您的客户在没有看到其特定系统上的实时漏洞利用的情况下不接受危险,那么他们不值得进行安全审计。

于 2011-12-01T10:46:12.463 回答
3

PHP 的 addlashes 是否容易受到 sql 注入攻击?

是的。与您链接到的文章中提到的条件。

我需要展示他们当前的漏洞。

我怀疑你可以显示这个,因为客户端的编码似乎不是著名的 GBK。

虽然,很可能存在其他可能的漏洞,只是因为人们倾向于误用转义函数,误以为它是错误的。

但我可以向您保证,只要您的客户端编码单字节或 UTF-8,并且只要正确使用此函数(如您发布的代码中所示),就不可能进行注入。

于 2011-12-01T10:36:45.610 回答
3

对于您的特定情况,执行 SQL 注入似乎并不容易,但是尝试的常见事情是,如果我输入 unicode null 变量?喜欢\0?它会破坏脚本并返回所有内容吗?很可能不是。

所以事情是,你并不总是需要斜杠来执行 SQL 注入。有些SQL可以写得这么可怕,举个例子

"SELECT * FROM admins WHERE id = $id"

如果$id是一个数字,它完全有效的 SQL,并且你addslashes在 $id 上执行,(谁会这样做呢?)。但是对于这种特定情况,SQL 注入所需要的只是1 OR 1=1使查询看起来像

"SELECT * FROM admins WHERE id = 1 OR 1=1"

没有办法addslashesmagic_quotes可以保护你免受那种愚蠢的影响。

回到手头的问题,为什么头脑正常的人会使用or之GBK类的东西?UTF-8UTF-16

于 2011-12-01T10:37:05.817 回答
-4

我不确定您为什么要在 mysql_real_escape_string() 上使用添加斜杠,但我想这完全是您的选择。

addslashes() 完全按照它所说的那样做:带斜杠的引号字符串

Example #1 An addslashes() example
<?php
$str = "Is your name O'reilly?";

// Outputs: Is your name O\'reilly?
echo addslashes($str);

但是有些 SQL 攻击可以不带引号执行(某些 shell 注入和一些盲 SQL 注入)。

出于这个原因,在这种情况下,我会亲自使用 mysql_real_escape_string() 而不是 addlashes() 来保护您的数据。

还可以考虑将 sprintf() 用于您的 sql 查询,因为它会稍微安全一些:

$query = sprintf("SELECT `username`,`password`
        FROM admins 
        WHERE user = '%s' 
        AND `pass` = '%s'", 
    $user, $pass);

它使它更安全,因为它不允许任何其他数据类型,而不是您提供的数据类型。

%d = 数字 %s = 字符串等。

我希望这有帮助。

于 2011-12-01T10:35:57.703 回答