【问题标题】:How vulnerable is my code to SQL injection?我的代码对 SQL 注入有多脆弱?
【发布时间】:2009-08-17 13:29:02
【问题描述】:

好的,我不希望这是一个黑客建议问题,所以请不要对此投反对票。我在一家网店工作,我发现我们的一些旧 PHP 页面很容易受到用户名中的 SQL 注入的影响,我想知道有多糟糕。

我们使用 PHP 字符串将来自 POST 的用户输入嵌入到登录表单中。

$uname = $_POST['username'];
$pass  = md5($_POST['pass']);
$sql = "SELECT * FROM users WHERE username='$uname' AND password='$pass' AND userlevel='user'";
...

然后我运行查询。

现在,我不是 SQL 专家,我只是在 phpMyAdmin 上使用我可以拼凑的东西。但是我可以在没有用户名的情况下登录,而是使用:

' OR 1 '

我知道要转义用户输入,我使用mysql_real_escape_string

我的问题是,这段代码有多脆弱,有人可以登录这个页面而不需要密码吗?我想也许他们不需要用户名,但只能暴力破解密码。但我不是 SQL 专家,我想知道是否可以对我们使用一些技巧。

我们使用 MySQL。

我不需要任何关于输入验证的讲座,我知道这有多糟糕。我们应该做很多事情,比如页面上的超时和锁定,这样它就不会被暴力破解。

【问题讨论】:

  • 什么是登录逻辑?如果 mysql_num_rows(query) == 1 可以吗?您必须获取密码(取决于用户名),然后检查密码是否相等...
  • 对不起,我投票结束。您在帖子中回答了自己的问题。
  • 嗯,不,我没有。我在问这是多么容易受到攻击,以及他们是否可以在没有密码的情况下登录。我还不清楚。

标签: php mysql security


【解决方案1】:

“有人可以登录此页面而不需要密码”:是的,很简单。试试用户名yourfavoriteadmin' OR 1; --

May as well link this, since certainly somebody will...

【讨论】:

  • 我试过了,但没用。你确定这适用于我的单引号吗?你能详细解释一下吗?是的,我知道那部漫画。 :)
  • 如果它不起作用,那是个好消息,但我不能说我知道为什么不。 :) -- 就像 C++ 中的 //,将行的其余部分指定为注释。
  • 嗯,有没有禁用cmets的mysql功能?
  • 这还取决于您的 PHP 版本 - PHP 将根据一周中 PHP 团队的突发奇想打开或关闭其各种“神奇”清理功能。因此,只要您在完全正确的 PHP 版本上运行,某些漏洞可能无法正常工作(除非有人随后使用 PHP 魔术函数中的编码漏洞来绕过它们)。
【解决方案2】:

它非常脆弱。如果你知道所有像mysql_real_escape_string 这样的好东西,你为什么要浪费时间问这个问题?你应该在那个代码上,修复它。你知道,比如,现在

【讨论】:

  • 已经修好了,我只是想知道后门打开了多久,谢谢大家!
【解决方案3】:

编写的代码在技术上根本不存在漏洞。您的 SQL 查询包含变量 $username 但您从未对其进行初始化或将其设置为任何值。这是一个错误,您永远无法从 MySQL 获得有效结果。

然而,一旦你修复了这个错误,你应该使用 mysql_real_escape_string() 转义你的变量。

http://us.php.net/manual/en/function.mysql-real-escape-string.php

【讨论】:

  • +1 用于指出错字。现在,只希望 register_globals 关闭,因为它可以让人们“初始化”$username。
  • 已修复。接得好。出于明显的原因,我没有复制和粘贴我的实际代码。 ;)
  • 我想到了 register_globals,但由于它默认关闭并且这是一个非常基本的问题,我猜测用户不太可能启用它。
【解决方案4】:

在用于任何 SQL 查询之前,请务必清理您的数据,如果您使用的是 PHP >= 5.2,则您有 the Filter functions

简单的问题:为什么不改变顺序 WHERE pass = 'blabl' AND username = 'bla' ? 你有这个字段的索引吗?

另一个问题:这条线有什么意义

$uname = $_POST['username'];

添加一个变量,只是为了在连接中引用/双引号效果?不过滤也不转义数据?

【讨论】:

    【解决方案5】:

    试试 $_POST['username'] 在哪里:

    no one'; delete from users --
    

    【讨论】:

    • 多条语句一般对php的mysql接口无效
    • 可爱,但你忘了FROM
    • 如果你使用 mysqli::multi_query,mysqli 接口会执行多个查询,但是你只是在自找麻烦 :)
    • @chaos,添加了“from”,在我大部分时间工作的地方是可选的(SQL Server)
    猜你喜欢
    • 2017-03-11
    • 2017-06-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-05
    • 1970-01-01
    • 2019-08-08
    • 2010-10-02
    相关资源
    最近更新 更多