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

时间:2011-12-01 10:30:01

标签: php addslashes

  

可能重复:
  What does mysql_real_escape_string() do that addslashes() doesn't?

我一直在评论关于PHP的addslashes函数如何/为什么容易受到sql注入攻击的文章。我读过的所有内容都说特定的mysql编码类型存在问题(default-character-set = GBK),或者如果启用magic_quotes则存在问题。但是,在这种情况下,我无法摆脱addslashes()函数并执行恶意操作 - 例如以管理员身份登录。

    $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 个答案:

答案 0 :(得分:3)

  

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

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

  

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

我怀疑你可以显示这个,因为看起来客户端的编码不是着名的GBK。

尽管如此,很可能存在其他可能的漏洞,只是因为人们倾向于滥用逃避功能,误解了。

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

答案 1 :(得分:3)

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

即使在特定情况下恰好是安全的,使用addslashes()的做法仍然很危险,而Shiflett的文章应该给你足够的材料来论证,即使利用所需的情况非常深奥,而且它们并不是完全无关紧要的。

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

答案 2 :(得分:2)

对于你的特定情况,它似乎并不像执行SQL注入那么容易,但是如果我输入一个unicode null变量,那么常见的事情是这样的吗?像\0?它会破坏脚本并返回所有内容吗?很可能不是。

所以,你并不总是需要斜杠来执行SQL注入。有些SQL可写得如此可怕错误,这是一个例子

"SELECT * FROM admins WHERE id = $id"

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

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

addslashesmagic_quotes无法保护您免受这种愚蠢的侵害。

要回到手头的问题,为什么心智正常的人会使用GBK而不是UTF-8UTF-16

答案 3 :(得分:-4)

我不确定你为什么要在mysql_real_escape_string()上使用addslashes,但我认为这完全是你的选择。

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)。

出于这个原因,我个人会在addslashes()上使用mysql_real_escape_string()来保护你的数据。

另外考虑使用sprintf()进行sql查询,因为它使它更安全:

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

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

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

我希望这会有所帮助。