我猜这个生成的 PHP 代码存在漏洞,我的想法正确吗?

3

我对PHP或Web安全等内容不是很了解,但我强烈怀疑公司正在使用的某些软件生成的代码是不安全的。

以下是我担心的一些片段:

第一个问题:

$sql = "SELECT password, fullname FROM ".$mysql_table." 
WHERE username = '".mysqli_real_escape_string($db,$_POST['username'])."'";

在PHP中,检索给定用户名的密码并进行比较,是否不好,还是更好的做法是在查询本身中使用密码,类似于这样:

... WHERE username = $username AND password = $hashed_password

第二个问题:
$crypt_pass = md5($_POST['password']);
if ($crypt_pass == $data['password'])
{
    //LOGIN SUCCESS
}

如果只使用MD5哈希而不使用盐,是否足够安全?

第三个问题:

 setcookie('username', $_POST['username'], time() + 3600*24*30);
 setcookie('password', $_POST['password'], time() + 3600*24*30);

在cookie中存储明文用户名和密码是否是一个好主意?

这段代码是否存在安全隐患,如果有,应该采取什么措施?


不,密码已经进行了MD5哈希处理并存储在数据库中。 - b00n
6
MD5不应用于存储密码。 - gabe3886
1
没有盐吗?有大量字符串的预计算哈希值,使得进行查找变得非常容易。 - Muhammad Abdul-Rahim
5
关于第三个问题,请勿将明文密码存储在任何地方,尤其是在Cookie中! - Muhammad Abdul-Rahim
2
我会担心密码没有被加盐,并且使用了MD5。第三个问题是最可怕的...只是明文传递用户名和密码对吗?这是通过HTTP传输的吗(请说不是)。 - Gil
显示剩余3条评论
2个回答

4

您还缺少一个问题:

问题: 这段代码使用"=="来检查哈希值的相等性。PHP会自动将这些字符串的第一部分强制转换成数字,然后比较这些数字的“有效”部分。例如,PHP将决定"0e"是一个科学计数法数字,其值始终为零。因此,任何以0e开头并且后面只包含数字的两个哈希值都将相互匹配。

"0e111111" == "0e123456"; # 在PHP世界中为真。

这里还有很多其他的问题。在PHP中,始终使用"==="来比较哈希值。

可能不是问题: 从数据库发送密码哈希值到Web服务器通常不会出现问题。如果攻击者可以监听该流量,那么你已经陷入了深深的麻烦之中。而另一种选择是将哈希值包含在查询数据库服务器的查询中——无论哪种方式,都需要通过链接传输信息。如果需要安全性,请考虑使用专门的身份验证系统,与数据库无关。

主要问题: 是的,您必须为每个用户生成长的盐值。如果没有长盐值,您用户的密码存储的就像明文一样。攻击者只需要在彩虹表中查找MD5哈希值,就可以找到相应的密码。例如,482c811da5d5b4bc6d497ffa98491e38看起来很安全,但是您可以查找它,发现它是"password123"。

主要问题: 在cookie中存储密码是可怕的。它将在每个请求中通过网络传输,在用户计算机上未加密地存储,并随着对您域中任何内容(如图像、已上传的任何恶意文件等)的每个请求一起发送。此外,这些cookie没有设置为HttpOnly,这意味着页面上的任何JavaScript(来自任何人)都能够读取用户的密码。


你确认了我大部分的担忧,但是"== vs ==="这个问题我之前不知道。谢谢。我写的所有代码都是使用WYSIWYG Web builder生成的。我猜应该远离那个应用程序。 - b00n

0

第一关注点

并不是特别关心。只要它能很好地防止XSS和SQL注入等攻击即可。但个人而言,我更喜欢将它们与数据库进行比较。

第二关注点

正如@gabe3886所说,MD5不应用于存储密码。我个人使用:http://www.openwall.com/phpass/。但是有很多哈希实现方法可以在网上搜索到。

第三关注点

不是的。请参见:https://dev59.com/tHI95IYBdhLWcg3w5iU4#2100386

应该使用什么代替: 好吧,我不知道为什么你甚至要在cookie中存储用户名和密码,将它们存储在数据库中就足够了。


密码存储在cookie中,被用作“记住我”功能。 - b00n
记住我是一个完全不同的话题。但绝对不应该通过存储实际的用户名和密码来实现。 - Elin
使用唯一的、随机的密钥与用户ID作为“记住我”令牌,并将其存储在数据库中。绝不要以这种方式实现“记住我”。 - Amelia
将其与 UA 字符串一起哈希,以便在不同的浏览器或另一台机器上无法重复使用。 - Elin

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