【问题标题】:Submitting passwords via ajax通过ajax提交密码
【发布时间】:2011-04-29 13:50:46
【问题描述】:

给定以下场景:我们有一个用于更改帐户密码的 html 表单。它看起来像这样:

CurrentPassword:   __________________
NewPassword:       __________________
NewPasswordAgain:  __________________

我们希望通过 ajax 调用发送此请求。如果我们发送它并离开我们的计算机(没有注销并停留在完全相同的页面上),那么有人可以打开 webkit 检查器(或 firebug)并看到如下内容:

http://cl.ly/3y213W1q0U2y2e251k0O

您有什么解决方案来提高安全性?甚至可以在此处使用 ajax 调用,还是使用“普通”html 表单在发送后重新加载整个页面会更好?

【问题讨论】:

    标签: javascript html ajax security


    【解决方案1】:

    使用“普通”的 html 表单也有同样的问题,因为数据包嗅探可以很容易地在 POST 或 GET 标头中发现相同的数据。

    我能想到的最佳解决方案是通过 javascript 在用户端加密密码。您真的不必担心“如果用户禁用了 javascript 怎么办?”情况,因为在这种情况下,AJAX 请求也不会通过。显然,这可能会对您存储密码的方式产生影响,但它将允许您继续使用 AJAX 请求来更新密码。

    【讨论】:

    • 普通表单提交与 OP 询问的问题不同。提交表单后,页面将重新加载,您将无法在检查器窗口中看到请求。两种方法(ajax 和普通表单提交)确实都有你提到的嗅探问题。所以在这种情况下,基于 ajax 的表单提交甚至比普通的表单提交更不安全:)
    • @cdes - 是的,但是监视 tcp 数据包流的人将能够读取包含密码数据的 POST(或 GET)数据包。这种数据包嗅探在未加密的网络上使用wireshark 和其他数据包嗅探器等工具是微不足道的。
    • 我 100% 同意你关于嗅探是多么容易并且这是一个问题,但 OP 是专门询问“计算机驱动”攻击方式。由于 OP 担心这种攻击(与嗅探攻击相比,它的讨论较少),因此连接可能已经是 SSL 连接。
    【解决方案2】:

    作者对这里的加密连接不感兴趣。他可能已经这样做了。他想要的是能够对任何有权访问计算机的人隐藏密码(和用户名),并且可以打开检查器工具来查看页面上发生的网络。

    您可以做的最简单的事情之一是在身份验证成功时刷新页面。

    您应该做的是每当用户按下“注销”时刷新页面。这应该会清除所有以前的网络数据。

    不太好的选择是在发送密码之前加密、混淆和散列密码。

    在客户端散列密码并不理想,因为这会阻止在服务器端使用散列密码和密钥(想想 HMAC)。 HMAC 的密码是最好的,因为密钥保存在文件系统中,而盐保存在数据库中。破解密码哈希需要相当可靠的系统访问权限。

    混淆和加密密码可以逆转。如果有人在 Webkit Inspector 上看到登录请求,他可能会非常有兴趣花时间解开你的防线。

    我强烈建议您在某个时候刷新页面以完全避免该问题。其他选项似乎不太好。

    【讨论】:

    • 值得注意的是,当前版本的 Chrome(可能还有其他浏览器)允许您在导航之间保留检查器日志,因此假设刷新会使日志空白不再正确。
    【解决方案3】:

    在传输时加密密码并确保您正在通过 SSL 进行调用!

    【讨论】:

      【解决方案4】:

      要在不使用 SSL 的情况下确保安全,请使用 SHA-2 在客户端上对密码进行哈希处理。虽然这将保护密码本身,但它不会保护某人免于嗅探 散列 密码。因此,您也不能简单地使用散列密码进行身份验证。

      一种方法是在身份验证时使用服务器生成的随机盐。为了进行身份验证,客户端向服务器请求 salt,然后对密码进行一次哈希处理(以匹配存储在服务器上的哈希版本),然后使用从服务器接收到的 salt 再次进行哈希处理,最后使用第二个 ajax 进行身份验证使用加盐哈希密码查询。

      只有当这与它自己存储的散列密码相匹配时,服务器才会进行身份验证,并使用之前提供给客户端的相同盐进行散列。

      这样,某人不可能使用密码的简单散列版本进行身份验证。由于服务器提供的每个盐只有效一次,因此基本上不可能有人拦截它并进行身份验证。 (他们必须拦截 salt 请求,然后尝试在合法客户端之前进行身份验证,同时欺骗他们的会话)。

      这可以在不使用 SSL 的情况下保护用户的密码,防止使用在合法用户进行身份验证时截获的数据进行登录,并且相当容易实现。当然,就保护您网站上的实际数据而言,SSL 是无可替代的,但是对于许多没有真正任何敏感信息的典型网站,您应该更加关注防止用户密码被盗,因为人们经常使用相同的密码。这解决了这个问题。

      请注意,这也无法防止会话劫持,但您可以通过在用户会话中包含特定于浏览器的信息、一次只允许一个活动会话以及要求重新验证以更改电子邮件地址或密码。

      【讨论】:

      • 我没想到,但你是对的......因为无论如何你都应该只处理服务器上的哈希密码,首先在浏览器中对其进行哈希处理,然后重新对其进行哈希处理在服务器上进行比较就可以了。
      • 密钥使用服务器提供的盐重新散列它,以便每次验证所需的散列都是唯一的。我已经开始普遍这样做了,因为我不想为某人的密码被泄露负责,而且一旦你的 sha 库就位,代码实际上只是几行代码。
      【解决方案5】:

      根据您需要的安全级别,您可以在发送 ajax 请求之前使用RSA 和公钥密码术在浏览器中加密密码。在服务器端,您将解密密码并正常处理它们。

      当然,您还需要小心删除用于保存输入密码的所有变量,我相信这其中还有其他安全漏洞,但加密至少可以为您提供一定程度的保护一种攻击。

      Here's one library I found 快速搜索。 (免责声明:我没有对此进行测试,但看起来还不错)

      最后,我强烈建议您通过SSL 传输所有登录信息。这在浏览器和服务器之间的整个浏览器会话之上增加了一层额外的安全性。

      【讨论】:

      • 要加密密码,客户端代码需要密钥,这也很容易受到攻击。
      • @Pointy - 使用公钥密码术,有一对密钥,一个是给用户用来加密消息的,另一个是隐藏的,只有这个人知道谁需要能够解密该消息。在对称密钥加密方案中,你说的是真的,但 RSA 不是对称的。
      • 好吧,我明白你的意思了。我想那可以正常工作;然而,这一切似乎都毫无意义,因为如果计算机确实无人看管,那么坏人可以访问浏览器会话并且可能会做很多事情。是否有任何实际的安全站点真的会做这样的事情?我从来没有听说过。
      • @Pointy - 大多数关注安全的网站(很多不关注)只是通过 SSL 连接进行正常的表单提交。
      猜你喜欢
      • 2017-05-17
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多