SPA 应该在哪里保存 OAuth 2.0 访问令牌?

Posted

技术标签:

【中文标题】SPA 应该在哪里保存 OAuth 2.0 访问令牌?【英文标题】:Where should a SPA keep a OAuth 2.0 access token? 【发布时间】:2019-10-11 06:18:11 【问题描述】:

授权码授予流程中,一旦公共客户端(例如单页应用程序 (SPA))获得 OAuth 2.0 访问令牌,SPA 应将其保存在哪里?

将访问令牌存储在语言环境存储或会话存储中会导致跨站点脚本 (XSS) 攻击,因此应避免这种情况。 将访问令牌存储在非 httpOnly cookie 中也会导致 XSS 攻击,因此也应避免这种情况。 在 httpOnly cookie 中存储访问令牌在技术上是不可能的,因为这是 httpOnly 的重点。

所以我看到的唯一安全的剩余选择是将其保存在内存中。它真的安全吗?这是唯一安全的方式吗?

【问题讨论】:

【参考方案1】:

一切都是关于你愿意接受的风险。

如果您将其存储在 cookie 中,您可能会向 CSRF 开放您的应用程序。虽然通过将令牌存储在 httponly cookie 中来交换 XSS 为 CSRF 可能是有意义的,但使用非 httponly cookie 这样做没有多大意义,除了 CSRF易受 XSS 攻击.

在许多情况下,将其存储在 localStorage 或 sessionStorage 中是可以的。选择它,您接受 XSS 访问令牌的风险。为了减轻这种风险,您可能需要实施缓解措施,例如使用合适的工具进行静态安全扫描、定期渗透测试等 - 安全不仅仅是代码,它还涉及您如何创建代码的过程。缓解措施到位后,您可以决定接受剩余风险。

您还可以将令牌存储在内存中,例如我猜想在 IIFE 中,从那里在 XSS 攻击中更难读取。将它存储在一个普通变量中没有帮助(来自 XSS 的 javascript 仍然可以访问),而且我不完全确定最新的 JS 可以做什么来安全地使其无法从给定对象外部访问。以一种实际上安全的方式可能是不可能的。

或者你可以走另一条路。您可以在 localStorage 中存储非常短暂的访问令牌,接受 XSS 访问的风险。但是,您的 IdP 可以在 IdP 域的 httponly cookie 中发出刷新令牌。这样即使访问令牌被泄露,它也只能在有限的时间内有效,然后攻击者将无法更新它。这在某些应用程序中可能有意义,而在其他应用程序中可能没有。

【讨论】:

以上是关于SPA 应该在哪里保存 OAuth 2.0 访问令牌?的主要内容,如果未能解决你的问题,请参考以下文章

存储位置 - OAuth 2.0 中的访问令牌和刷新令牌

OAuth 2.0 在哪里安全地存储访问令牌以供长期使用

我在哪里可以检查 google oauth 2.0 access_token 是不是有效?

使用 OAuth 2.0 Google App Engine 刷新访问令牌

OAuth 2.0 访问令牌未加密?

SPA 如何在 OAuth2 隐式流中提取访问令牌