在单页应用程序(JavaScript)通过OIDC服务器进行身份验证的情况下,保持会话有效(在令牌过期后获得更多令牌)的标准和推荐方法是使用HttpOnly Cookie并在iframe内执行静默续订。很棒,因为浏览器无法保密,所以不涉及刷新令牌。
现在看来,浏览器将阻止跨源Cookie(Safari和Brave已经这样做了,Chrome似乎将是下一个),因此,如果服务器在不同的域上,那么未来的唯一方法似乎是使用刷新令牌和更新令牌轮换(可能还有重用检测),这似乎可以缓解问题。但真的吗?
场景1) 刷新令牌(RT1)被盗,由于轮换,用户请求新的令牌并取回新的刷新令牌(RT2)。RT1现在无效,攻击者无法使用。太棒了
场景2) 刷新令牌(RT1)被盗,攻击者执行获取新令牌(RT2)的请求,用户使用旧令牌(RT3),现在所有内容都被丢弃,用户必须再次登录(重用检测),攻击者的令牌也无效。太棒了我在这里看到了一个问题(用户必须再次登录,不知道为什么),但至少问题已经解决了。
场景3) 这是我在任何地方都没有提到的场景。假设攻击者在不使用它们的情况下窃取了随后的每个RT,因此它继续窃取RT1。用户刷新,攻击者也窃取RT2。一切正常,因为攻击者没有使用令牌,但可能他将所有令牌都发送到了其他地方进行存储。最后,用户关闭窗口,攻击者提取了RT1和RT2。此时,攻击者可以使用最新的RT(RT2)模拟用户,直到用户返回应用程序。假设他离开一周,攻击者有一周的新访问令牌(他可以不断刷新令牌)。直到最后,没有人注意到任何事情。有了Cookie,攻击者只能在浏览器会话期间进行操作,现在有了更多的时间。
所以。。。带有重用检测的RTR真的足够安全吗?主要论点是";这总是一种风险/收益选择";,我明白了,但怎么可能是2020年,我们的浏览器仍然有问题?你认为我遗漏的第三个场景有什么问题吗?老实说,会话cookie一直是最好的选择,浏览器会阻止我们在这种常见情况下使用它们,这让我抓狂:)
谢谢。
PS。我将在这里复制我找到的关于这个问题的一些资源:
- https://pragmaticwebsecurity.com/articles/oauthoidc/refresh-token-protection-implications.html
">RTR不是一种包罗万象的安全措施。如果攻击者设法在应用程序关闭前获得最后一个刷新令牌,他们可能能够继续旋转被盗的刷新令牌。为了避免长期滥用被盗的刷新令牌,安全令牌服务可以将该刷新令牌的生存期与用户与安全令牌服务的会话的生存期链接起来。这样做会在会话过期时使刷新令牌无效";
这是我在场景3中提出的观点,但他建议的解决方案是将RT链接到用户的会话。那么,我们又在使用会话Cookie了,不是吗?如果我们不能使用它们呢?当我们不能使用跨域cookie时,这种情况下的RT应该是一种替代方案。
- https://leastprivilege.com/2020/03/31/spas-are-dead/
这个似乎同意我的观点,即即使使用RTR的RT也不够安全,SPA需要连接到同一域上的后端才能像以前一样工作。
这是一个有趣的领域,它通常是可用性、安全性、性能和成本之间的权衡。该行业目前的状况非常不令人满意,但我希望其中的一些能帮助你理解主要问题。
刷新浏览器中的代币
在使用此解决方案之前,我会确保授权服务器正确支持OAuth 2.1 RTP建议-没有多少授权服务器支持
然后我会确保我只在应用程序的内存中存储刷新令牌,因为不建议在本地存储中存储令牌。这意味着:
- 多选项卡浏览或重新加载页面将需要通过您提到的基于iframe的旧解决方案进行令牌刷新
- 这在Safari中不会悄无声息地工作,因此会出现可用性利益相关者可能会抱怨的浏览器重定向
安全方面
当然,您的SPA安全不仅仅是代币机制。您需要确保安全利益相关者接受该解决方案,并且需要考虑威胁,例如攻击者可以使用令牌/cookie做什么。
后端用于前端模式
这方面的一个大问题是,您通常需要一个后端,该后端只发布相同域的HTTP加密cookie,用C#、Node、Java等进行编码。
这对于SPA架构来说可能是非常具有侵入性的:
- 通过内容交付网络将web静态内容推送到许多全球位置要么不可能,要么更困难
- 您可能需要对来自SPA的每个API调用进行双跳,这会增加复杂性,尤其是在缓存和API错误响应等领域
- 使用authcookie并不能"解决"安全问题,许多浏览器威胁仍需处理
2022更新
这些天,我建议将代币排除在浏览器之外,因为现在人们对这一点的看法很差。也许可以将令牌处理程序模式视为一种现代解决方案。