【问题标题】:Protect against SQL injection防止 SQL 注入
【发布时间】:2011-06-12 14:01:47
【问题描述】:

我正在开发一个网站,我正在尝试保护连接部分。

我在$login 上使用了addslashes 函数来阻止SQL 注入,但是一些朋友告诉我这还不够安全。但是,他们没有向我展示如何利用此漏洞。

我/你可以如何破解此代码? 我该如何保护它?

<?php

    if ( isset($_POST) && (!empty($_POST['login'])) && (!empty($_POST['password'])) )
    {
        extract($_POST);
        $sql = "SELECT pseudo, sex, city, pwd FROM auth WHERE pseudo = '".addslashes($login)."'";
        $req = mysql_query($sql) or die('Erreur SQL');
        if (mysql_num_rows($req) > 0)
        {
            $data = mysql_fetch_assoc($req);
            if ($password == $data['pwd'])
            {
                $loginOK = true;
            }
        }
    }
    ?>

【问题讨论】:

  • google addlashes VS mysql_real_escape_string : sitepoint.com/forums/showthread.php?t=337881
  • 有许多过时的教程建议将addslashes() 作为一种机制来逃避 SQL 查询中的内容。如果您正在从中学习其中之一,我建议您尝试找到更最新和更准确的东西。此外,extract($_POST) 是一个很好的漏洞示例;不要这样做!顺便说一句,欢迎来到 StackOverflow。
  • 这就够了,只要你使用的是单字节或 utb-8 编码。
  • 然而你正在遭受最严重的注射,超出了extract() 功能。如果表单中有loginOk字段怎么办?..

标签: php sql security sql-injection


【解决方案1】:

您应该使用mysql_real_escape_string 在查询中转义字符串输入参数。使用类型转换来清理数字参数并使用白名单来清理标识符。

在引用的PHP页面中,有一个登录表单中的sql注入示例。

更好的解决方案是使用准备好的语句,您可以使用PDOmysqli 来做到这一点。

【讨论】:

  • 好的,但是你能给我这个代码的 SQL 注入示例吗?我不明白如何破解这段代码,而我正在转义其中的引号。
  • mysql_real_escape_string 单独不足以替代 addlashes。很可能在您的代码中,这些函数之间没有区别
  • 我已经看过这篇文章了。但我没有成功破解我的代码。你能给我举个例子吗?
  • 你错了,“根本不容易被注射”。如果您要查询"ORDER BY $sort_field",该怎么办。而且,如果没有mysql_set_charset,您的 mysql_real_escape_string 的行为将与添加斜杠完全相同。
【解决方案2】:

您正在以明文形式存储密码!如果我看到过,那将是一个重大的安全问题。该怎么做:至少使用(每个用户)密码的加盐哈希,如所见,例如here.

【讨论】:

  • (随意编辑以更好地解释散列和加盐,这是我通过快速搜索找到的)
【解决方案3】:

用途:

mysql_real_escape_string($inputToClean);

【讨论】:

  • 这个函数被单独调用只能做addlashes
  • @Col。弹片:它比 addslashes (Unicode 表示和诸如此类)更好 - 但你是对的,程序员将它用作 abracadabra-it-is-now-secure 魔法灰尘并不比使用 addlashes 更安全。
【解决方案4】:

还有另一个巨大的安全漏洞 - extract。它可能会让您免于输入几个字符,但会打开太多无法提及的漏洞,因为它会覆盖任何全局变量。

如果我发布这个会发生什么?

$_POST {
    'login' => 'Admin',
    'loginOK' => 1
}

猜猜看,现在 $loginOK == 1 ,我将以管理员身份登录。

以后省去很多麻烦,只使用你想使用的变量,而不是依赖于可怕的黑客extract

【讨论】:

  • @Tom-pouce:不客气。顺便说一句,这正是针对extract 的情况eeexactly - 它“无中生有”地创建了变量(我被这个咬过,而且真的很难调试)。
【解决方案5】:

除了addslashes()的用法,以下是这段代码中发现的一些随机问题:

  • isset($_POST) 始终是 TRUE,除非您从命令行运行它。您可能可以删除它。
  • empty() 非常棘手。例如,如果$password = '0'empty($password)TRUE
  • 您可以这样做:if( isset($_POST['login']) &amp;&amp; $_POST['login']!='' ){}
  • extract($_POST) 是一个巨大的漏洞:任何人都可以从外部在您的代码中设置变量。
  • $password == $data['pwd'] 建议您在数据库中存储纯文本密码。这是一种可怕的做法。谷歌搜索“盐渍密码”。
  • 你也可以$loginOK = $password == $data['pwd'];。你知道为什么吗? ;-)

【讨论】:

    【解决方案6】:

    你应该使用mysql_real_escape_string而不是addslashes

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-03-23
      • 1970-01-01
      • 2019-06-22
      • 2013-08-31
      • 2019-06-03
      • 2015-09-07
      • 1970-01-01
      相关资源
      最近更新 更多