我的代码有多容易受到SQL注入攻击?

4

好的,我不想让这个问题成为一个黑客建议问题,所以请不要因此而投反对票。我在一个网络商店工作,发现我们一些旧的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,那就可以了吗?您必须获取密码(根据用户名),然后检查密码是否相等... - Svetlozar Angelov
抱歉,但我投票关闭。你在帖子中已经回答了自己的问题。 - ryeguy
嗯,我没有。我在问这个有多严重的漏洞,以及他们是否可以无需密码登录。对我来说仍然不清楚。 - tkotitan
5个回答

10

我尝试了那个,但是没起作用。你确定这适用于我的单引号吗?你能详细说明一下吗?是的,我知道那部漫画。 :) - tkotitan
如果它不起作用,那是好消息,但我不能说我知道为什么。 :) “--”就像C++中的“//”,表示该行剩余部分为注释。 - chaos
哦,有没有禁用注释的mysql功能? - tkotitan
这也取决于你使用的 PHP 版本 - PHP 的各种“神奇”清理功能会根据 PHP 团队当天的心情开启或关闭。因此,只要你在完全正确的 PHP 版本上运行,某些漏洞可能就无法生效(除非有人利用 PHP 魔术函数中的编码漏洞来绕过它们)。 - David

9

这段代码非常脆弱。如果你了解所有巧妙的技巧,比如mysql_real_escape_string ,为什么浪费时间来问这个问题呢?你应该立即着手修复那些代码。你知道的,就像现在这样。


已经解决了,我只是想知道后门开放多久,谢谢大家! - tkotitan

2

代码本身并没有漏洞。你的 SQL 查询包含变量 $username,但你从未对其进行初始化或设置任何值。这是一个错误,你将永远无法从 MySQL 中获得有效的结果。

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

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


+1 指出了拼写错误。现在,只希望 register_globals 被关闭,因为这可能会允许人们“初始化”$username。 - Michael Stum
修复了。干得好。出于明显的原因,我没有复制粘贴我的实际代码。 ;) - tkotitan
我考虑过register_globals,但由于它默认是关闭的,而且这是一个非常基本的问题,所以我猜用户不太可能启用它。 - Brandon

0

尝试检查 $_POST['username'] 的位置:

no one'; delete from users --

通常情况下,使用PHP的MySQL接口时,多个语句通常没有任何效果。 - Paul Dixon
可爱,但你忘了 FROM - chaos
mysqli接口将执行多个查询,如果您使用mysqli :: multi_query,则只会引发麻烦 :) - Paul Dixon
@chaos,添加了“from”,但在我大多数时候工作的地方(SQL Server)是可选的。 - KM.

0

在使用任何SQL查询之前,始终清理您的数据。如果您正在使用PHP> = 5.2,则可以使用{{link1:过滤函数}}。

简单的问题:为什么不更改WHERE pass ='blabl' AND username ='bla'的顺序?您在这些字段上有索引吗?

另一个问题:这行代码有什么意义?

$uname = $_POST['username'];

添加一个变量,只是为了在连接时进行引用/双引号效果?而不过滤或转义数据吗?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接