为什么 auth0 建议不要在 localStorage 中存储令牌?

Uri*_*iel 5 jwt single-page-application auth0

Auth0 提供了大量资源列表,描述了身份验证的最佳实践。其中有一连串建议不要localStorage用作存储 (JWT) 令牌的手段。

我发现这些点有几个问题:

  • 强烈假设 JWT 令牌是攻击者不得访问的敏感信息(通过 XSS)
    • 从我的角度来看,访问令牌本身并没有扩大攻击范围。如果攻击者可以控制受害者的浏览器,他们可以使用令牌从受影响的浏览器本身执行调用。
    • 访问令牌通常具有相当短的到期时间,并且它们可以被浏览器固定,从而减少在 XSS 上下文之外使用它们的机会。
  • Auth0 建议使用auth0.getTokenSilently()他们的 SDK 来获取令牌,但据我所知,攻击者没有任何理由不能自己调用​​这个方法(即注入另一个 sdk 脚本,使用现有的客户端密钥,并且只是调用getToken 从那里),从而以几乎相同的方式获取令牌,就好像它存储在localStorage
  • 我知道 XSS 无法访问令牌的唯一方法基本上是使用 httpOnly cookie,但这本身会创建新的向量 (CSRF),并且仍然无法阻止攻击者从受影响的浏览器中调用 api。

所以我完全同意 OWASP 的建议,不要将敏感数据localStorage存储在 . 但这只是因为这些东西会允许攻击者扩大攻击范围(访问银行帐户,尝试在其他应用程序中重复使用用户的密码等)。但我很难看出 accessTokens 是如何受此影响的。

Sap*_*asu 4

虽然我对 Auth0 实现、功能和设计决策了解不多,但从我对 OAuth2 和安全性的一般理解来看,我可以尝试将这些点联系起来。

\n
\n

单个建议本身并不能提供足够的安全性或所需的功能,但是当与其他相关建议组合使用时,我们可以实现所需的安全性和行为级别。

\n

让我们回顾一下您提出的观点。

\n
\n

从我的角度来看,访问令牌本身并不会扩大攻击范围。如果攻击者可以控制受害者的浏览器,他们可以使用令牌从受影响的浏览器本身执行调用

\n
\n

问题localstorage是:

\n
    \n
  1. localStorage并且sessionStorage不跨子域共享。这是 SSO 功能的显示阻止程序(有一些解决方案使用iframe,但这些看起来更像是解决方法,而不是一个好的解决方案。当使用响应标头 X-Frame-Options 来避免使用 进行点击劫持攻击时iframe,任何使用 的解决方案都不iframe可用问题)

    \n
  2. \n
  3. XSS 可以将访问和/或刷新令牌发送到攻击者控制的远程服务器,从而允许攻击者冒充用户

    \n
  4. \n
\n

注意:第 2 点中提到的漏洞可以通过使用发送者受限访问令牌方法来缓解,其中客户端必须证明他们确实拥有该令牌。另一种选择是OWASP 中提到的指纹方法,它需要 cookie。然而,Auth0 似乎没有实现这些。因此,避免的建议localstorage是有道理的。

\n
\n

Auth0 建议使用其 SDK 中的 auth0.getTokenSilently() 来获取令牌,但据我所知,攻击者应该没有任何理由无法自己调用此方法

\n
\n

正确的。这就是为什么

\n
    \n
  1. 我们首先需要遵循OWASP XSS 预防指南来降低 XSS 风险。
  2. \n
  3. 此外,该getTokenSilently()方法要求您Allow Skipping User Consent在仪表板的 API 设置中启用。虽然我没有看到这方面的具体指南,但我认为如果您将令牌存储在 cookie 中,则不需要启用此选项,从而消除了滥用该方法的任何可能性。
  4. \n
\n
\n

我知道 XSS 无法访问令牌的唯一方法基本上是使用 httpOnly cookie,但这会自行创建新向量 (CSRF),并且仍然无法阻止攻击者从受影响的内部调用 api浏览器

\n
\n

真的。但您可以通过以下一种或多种方法的组合来缓解这种情况:

\n
    \n
  1. 使用SameSitecookie。请参阅此处的文档。如果浏览器不支持SameSitecookie,请按照下面的另一种方法
  2. \n
  3. 状态变量(Auth0 使用它)- 客户端将生成并通过每个请求传递一个加密的强随机数,服务器将回显该随机数及其响应,从而允许客户端验证该随机数。Auth0 doc中对此进行了解释。
  4. \n
  5. 使用具有加密强随机值的 CSRF cookie,以便每个 AJAX 请求都会读取 cookie 值并将 cookie 值添加到自定义 HTTP 标头中(GET 和 HEAD 请求除外,它们不应进行任何状态修改)。由于 CSRF 由于同源策略而无法读取任何内容,并且它基于利用 POST、PUT 和 DELETE 等不安全的 HTTP 方法,因此此 CSRF cookie 将减轻 CSRF 风险。所有现代 SPA 框架都使用这种使用 CSRF cookie 的方法。这里提到了Angular的方法
  6. \n
  7. 始终检查 Referer 标头,仅当 Referer 是受信任域时才接受请求。如果引用标头不存在或域不在白名单中,则只需拒绝该请求即可。使用 SSL/TLS 时,通常会出现引用者。登陆页面(主要是信息性的,不包含登录表单或任何安全内容可能有点宽松 \xe2\x80\x8band 允许缺少引用标头的请求
  8. \n
  9. TRACE HTTP 方法应该在服务器中被阻止,因为它可以用来读取 httpOnly cookie
  10. \n
  11. 另外,将标头设置Strict-Transport-Security: max-age=<expire-time>; includeSubDomains\xe2\x80\x8b为仅允许安全连接,以防止任何中间人覆盖来自子域的 CSRF cookie
  12. \n
\n