Obv*_*uit 11 security xss rest csrf single-page-application
我一直在研究如何最好地在单页应用程序(SPA)中存储身份验证令牌。SO 上关于这个主题存在一些争论,但据我所知,没有一个提供具体的解决方案。
昨天和今天花了很多时间在互联网上寻找答案,我发现了以下内容:
本地存储API。我发现一些基本指南建议使用localStorage(尽管许多人正确地建议反对)。我不喜欢这种方法,因为存储的数据localStorage在发生 XSS 攻击时可以被访问。
网络工作者。如果令牌存储在 Web Worker 中,则打开新选项卡时用户将不会登录。这导致了不合格且令人困惑的用户体验。
关闭。与 Web Workers 相同 - 没有持久性。
仅 Http Cookie。一方面,我读到这可以防止 XSS。然而,另一方面,这是否意味着我们现在必须处理CSRF?那么这就完全是一场新的争论:如何使用 SPA + REST API 实现 CSRF 令牌?
其他人都是怎么做的?
yma*_*ros 11
我很高兴你问这个问题。前端经常出现关于 oauth2 的模因,这确实污染了辩论,并且很难找到事实信息。
首先,关于我建议重新考虑的一些排除选项:如果您需要在多个选项卡上进行相同的身份验证,您仍然可以使用将令牌存储在窗口范围内的任何选项,但单独管理令牌并在页面刷新时获取新令牌(无提示)刷新,因此标准提示=无流)。这打开了一些选项:服务工作者、网络工作者、闭包……确实,其中一些最初并不是为了这个目的,但它很好地解决了问题。这还解决了一系列有关刷新令牌的竞争条件(它们只能使用一次,因此每个选项卡都有一个可以解决一堆问题)。
话虽如此,以下是选项:
本地存储:如果 XSS 攻击成功,令牌可能会被盗。XSS = 无论如何游戏结束(在这种情况下,没有黑客会关心你的令牌,这是不需要的)。与 cookie 的典型小时/天有效性相比,还可以通过使用短期令牌来缓解这种情况。无论如何,建议使用短期代币。
现在,XSS 导致的令牌被盗对于某些人来说似乎是一个重要问题,所以无论如何让我们看看其他选项。
会话存储:与本地存储相同的缺点(XSS 可能导致会话泄漏),引入了自己的 CSRF 问题,但也解决了其他一些问题(刷新...)。
Web Workers:这实际上是一个很好的解决方案。如果应用程序的随机部分成功发生 XSS,它将无法窃取令牌。理论上,如果可以注入一些在身份验证(身份验证代码或令牌交换)时运行的脚本,它也可能被利用......但这对于所有流都是如此,包括 cookie/会话。
闭包:与网络工作者相同。不太孤立(更容易被窃取您代币的人替换)。
Service Worker:我认为理想的解决方案。易于实现(您只需拦截获取请求并在几行代码中添加您的令牌)。无法被XSS注入。您甚至可以说它实际上是针对特定用例的。它还解决了页面上多个应用程序的情况(它们共享 1 个服务工作线程,在需要时添加令牌),而其他选项都不能很好地解决这个问题。唯一的缺点:浏览器可以终止它,您需要实现一些东西来延长它的生命周期(但有一个记录在案的标准方法)。
HttpOnly Cookies:简而言之,您将过渡到传统的服务器端 Web 应用程序(至少对于某些部分),它不再是具有标准 oidc 或 aouth2 的独立 SPA。这是一个选择(现在已经不是我的选择了),但它不应该是由代币存储驱动的,因为有一些选择甚至是安全的,可以说是更好的。
结论:我的建议是仅使用本地/会话存储。无论如何,成功的 XSS 可能会让您失去工作或失去客户(提示:当他们可以调用 API 时,没有人会对您的令牌感兴趣pay(5000000, lulzsecAccount))。
如果您对令牌存储很挑剔,那么 Service Worker 是我认为的最佳选择。
| 归档时间: |
|
| 查看次数: |
4522 次 |
| 最近记录: |