如果其他字段的验证失败,我正在尝试通过不要求用户重新输入密码来改善用户注册体验。有几种方法可以实现这一点,例如使用会话 cookie 并在服务器端存储密码的哈希值。我正在探索这种将用户密码临时存储在客户端而无需服务器跟踪的替代方案。这种方法可行吗?涉及哪些风险?
将密码存储在 HTML5 sessionStorage 中是否安全?
原则上,存储在 sessionStorage 中的值被限制为相同的方案 + 主机名 + 唯一端口,如果浏览器有一个干净的退出,这些值应该在会话结束时删除。然而,根据这篇文章,如果用户在崩溃后选择“恢复会话”,它可以在浏览器重启后幸存下来(这意味着它的值也存在于持久内存中,直到它们被清除,所以请记住这一点)。如果实施得当,我会说它足够安全 - 特别是与您使用 cookie 的替代方案相比(它有很多我什至不会考虑的陷阱)。W3C 规范还指出,Web 存储确实可能用于存储敏感数据(尽管尚不清楚这种做法是否得到认可)。
至于风险,这只是一个权衡问题:您正在使您的网站对您的用户更方便,同时增加一点捕获密码的机会窗口(通过 XSS 漏洞,通过该值在持久存储中的持续时间超过您的预期,或者用户在完成注册之前离开计算机无人看管)。理想情况下,密码永远不应离开 RAM,但这通常是不切实际的,因此需要做出一些妥协。我只是建议在注册成功后立即从 sessionStorage 中清除密码,并密切关注可能最终暴露的 sessionStorage 实现的漏洞。
我建议另一种方法:不要将表单提交到服务器,而是使用 XMLHttpRequest 来创建帐户。如果服务器端验证失败,表单及其所有内容仍然可用。如果成功,则重定向到目标页面。
这需要启用 JavaScript,但您仍然可以退回到正常的表单提交。无论如何,访问 SessionStorage 也需要 JavaScript。
如果两个存储值都不是空的但由于某种原因不同,您将很难决定将哪个存储值用作用户的预期密码(本地存储中的一个,或输入字段中的一个)。
这可能会提供社会工程攻击向量,攻击者通过打开注册表来准备陷阱,使用您自己的代码填充本地/会话存储,然后使用 DOM 删除它的任何痕迹(输入错误通知)编辑器,或者直接在本地/会话存储中输入所需的密码(某些浏览器都支持这两种方法,并且非常容易做到),然后要求受害者在您的网站上注册并使用它。由于可以轻松检查/测试您的代码以了解您如何处理此类情况,因此攻击者的执行方式可能与我描述的略有不同(如果您稍后处理,即使直接在本地/会话存储中进行脚本注入也不是不可能的POST 表单上的本地值),但效果相同。
在她注销并尝试重新登录之前,受害者不会怀疑任何事情。根据用户会话的持久性,注销和重新登录的过程可能不是必需的,并且受害者不会注意到她密码不是她在密码字段中输入的密码,而是攻击者选择的密码用于创建她的新帐户。
不用说,攻击者只是获得了对受害者新创建的帐户和受害者输入的所有数据的访问权限,即使受害者很谨慎并确保没有涉及偷窥。
因此,这里的要点是,您可能必须处理系统相同注册数据的两个不同位置,无论出于何种原因,这可能会有所不同,并决定以对您的系统安全的方式使用哪个位置,以及正在注册的最终用户。这可能证明要正确执行非常棘手,所以我建议不要这样做。
相反,请确保您的注册表单是通过 HTTPS 提供的,然后只需填写密码字段,因为它是在用户的 POST 请求中最后输入的,并且如果它满足您的限制,即使其他一些输入字段填写不正确并且表格需要重新发布。
我会使用一些 intertab 通信来分发密码,而不是将密码存储在任何持久存储中(cookie、localstorage 等。有无数的解决方案,检查 evercookie)。这样,密码将存在于浏览器中,直到您关闭实际域的最后一个选项卡。
BroadcastChannel
您可以使用或可能有其他我不知道的方法安全地进行 intertab 通信SharedWorker
,它们总是在重新发明轮子。postMessage
前两个将消息发送到每个选项卡,最后一个仅发送到从同一父选项卡打开的选项卡,因此它有些限制,但更多浏览器支持。
如果将密码存储在 js 内存中,则需要防止带有特殊 headers的 XSS 。和ofc。您需要检查 HTML 标记的显示内容,并且始终需要 JSON 编码要直接注入 javascript 作为变量的数据。
TildalWave 的帖子很有趣,我认为这些方法不会受到攻击,因为同步几乎是即时的,您也可以同步登录、注销等。
如果您决定使用 localstorage,最好使用签名的用户 ID、超时和盐,而不是密码本身。您可以将凭据发送到服务器,服务器可以对其进行验证,然后将带有签名的数据发回。它们可以存储在 cookie 或您想要的任何持久存储中。如果有浏览器客户端,REST API 有时会使用这些令牌,因为这种解决方案是无状态的,并且仍然给人一种拥有经典会话的感觉。有时他们会签署每个请求,而不仅仅是用户 ID 以增强安全性。