对于 HTTPS Web 应用程序,是否值得在发布密码之前对其进行加密,以防止 MITM 攻击者窃取它?

信息安全 tls 密码 中间人
2021-09-04 00:15:19

我们的应用程序最近通过了渗透测试。测试发现了一个严重的安全漏洞,本质上是:

问题:

  • 攻击者设置了一个 WiFi 点。
  • 用户进入我们的网站(HTTPS)。
  • 使用像 Cain 这样的工具,攻击者要么将用户重定向到 HTTP,要么使用欺骗性证书将用户保留在 HTTPS 中。(无论哪种方式,用户都必须通过“让我离开这里”/“添加例外”页面)
  • 用户输入她的用户名和密码。
  • 密码被发布给 MITM 攻击者,他们可以看到它。显然 Cain 有一个自动获取用户名和密码的功能,我们的密码很容易在那里被抓到。

建议的解决方案

该报告建议在客户端加密或散列密码(使用 JavaScript),以一种无法重放的方式(例如使用一次性密码/时间戳)。他们无法推荐特定的架构(他们确实提到了客户端证书,这对于大型应用程序可能不切实际)。

在发布密码之前是否值得加密或散列密码?这是常见的做法吗?

3个回答

这个建议毫无意义:用于散列或加密密码的 JavaScript 代码也必须传输到客户端。如果攻击者能够发起中间人攻击,他将能够检查用于加密的 JavaScript 代码,甚至可能用其他东西替换它(比如不加密)。

散列而不是加密更没有意义,因为这只有在服务器接受散列密码而不是真实密码时才有效。在这种情况下,攻击者甚至不需要知道密码,他只需要知道哈希。

可能有帮助的是客户端证书,因为您无法安装 SSL 中间人攻击来保留客户端证书(并且降级到纯 HTTP 也不会发送证书)。但是,因为您必须先将证书分发给客户端并让他们将其安装在浏览器中,所以此解决方案仅在您的客户端很少时才有效。

除此之外:如果攻击者在中间,他可能根本不需要密码。他所需要的只是受害者已经登录,然后攻击者可以接管现有的会话。

检测这种中间人情况也可能很有用,这样您就可以通知用户并拒绝从受感染的网络登录。检测连接降级的一些想法(即向攻击者发送 http,然后将其作为 https 转发):

  • 使用 JavaScript 检查当前位置的方法。
  • 使用 JavaScript 创建安全 cookie。仅当使用 https 提供站点时才应将其发回(即没有降级)。
  • 包含一个作为 HTTP 的脚本,该脚本为图像提供服务,并在服务器端检查图像是如何包含的。如果它作为 HTTPS 包含在内,则可以假定 HTTP 降级攻击,因为您已将其明确包含在 HTTP 中。如果它被 HTTP 访问,你也有降级攻击(但有一个更聪明的攻击者)或者浏览器不关心混合内容。

以及如何使用伪造的证书检测中间人:

  • 设置第二个 https 站点(使用不同的主机名)并以某种方式向该站点构造一个 ajax 请求,这对于攻击者来说更改为 http 并不简单(例如,动态创建 URL)。如果攻击者只是尝试 MITM 任何站点,这个 ajax 请求至少在某些浏览器中会失败,因为证书不受信任,并且浏览器只会提示用户输入站点的主证书。

当然,所有这一切都只有助于对抗一个没有真正决心攻击的攻击者,尤其是你,而只是攻击最简单的目标。在这种情况下,您需要做的就是比其他人更难攻击。

我建议改为实施HTTP Strict Transport Security,这可以防止用户首先接受欺骗的证书。

如果您想忽略攻击者可以在活动 MITM 攻击期间轻松替换 Javascript 代码:

您可以生成一些非对称加密密钥,向客户端提供该公钥以使用它来加密客户端的密码。如果每次登录都使用新密钥,那么没有人应该能够重播密码。