【问题标题】:Am i right in suspecting that this generated PHP code is vulnerable?我怀疑这个生成的 PHP 代码很容易受到攻击是对的吗?
【发布时间】:2015-05-21 23:30:46
【问题描述】:

我一般来说对 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 中是个好主意吗?

这些代码是否不安全,如果是,应该怎么做?

【问题讨论】:

  • 您是否以明文形式存储密码?如果是这样,那绝对是一个问题! :P
  • MD5 不应用于存储密码。
  • 没有盐吗?有大量字符串的预先计算的哈希值,这使得进行查找变得微不足道。
  • 关于第三个问题,永远不要在任何地方存储明文密码,尤其是在 cookie 中!
  • 我会担心密码没有加盐,并且正在使用 MD5。第三个问题是最可怕的......简单地传递一个用户名和密码对(这是明文密码吗?)?这是通过 HTTP 的吗(请拒绝)。

标签: php security web


【解决方案1】:

实际上您还缺少一个问题:

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

"0e111111" == "0e123456"; # true, in PHP world.

还有更多可能出错的方法。在 PHP 中始终使用“===”来比较哈希。

可能不是问题:将密码哈希从数据库发送到 Web 服务器不太可能成为问题,如果攻击者可以侦听该流量,那么您已经陷入困境。另一种方法是在对数据库服务器的查询中包含您的散列值 - 无论哪种方式,链接都会发生一些事情。如果您需要这里的安全性,您可能需要一个与您的数据库无关的专用身份验证系统。

主要问题:是的,您必须拥有每个用户长的盐。如果没有长盐,您的用户密码将存储在粗略的纯文本中。攻击者只需在彩虹表中查找 MD5 哈希值即可查看相应的密码。例如,482c811da5d5b4bc6d497ffa98491e38 看起来很安全,但您可以查找它以找出它是“password123”。

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

【讨论】:

  • 你证实了我的大部分担忧,但我不知道“== vs ===”的事情。谢谢你。我编写的所有代码都是使用WYSIWYG Web builder 生成的。我想应该远离那个应用程序。
【解决方案2】:

首要关注

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

次要关注

正如@gabe3886 所说,MD5 不应用于存储密码。我个人使用:http://www.openwall.com/phpass/。但是周围有大量的哈希实现。尝试搜索网络。

第三个关注点

不,不是。见:https://stackoverflow.com/a/2100386/3455727

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

【讨论】:

  • 在 cookie 中存储密码被用作“记住我”功能。
  • 记住我是一个完全不同的话题。但绝对不应该通过存储实际的用户名和密码来实现。
  • 使用一个唯一的、随机的密钥加上用户 ID 作为记住我的令牌,并将其存储在数据库中。永远不要以这种方式记住我。
  • 并使用 UA 字符串对其进行哈希处理,这样它就不能在不同的浏览器或另一台机器上重复使用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-19
  • 2014-02-23
  • 2016-04-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多