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

Jwt 为什么auth0建议不要在localStorage中存储令牌?,jwt,single-page-application,auth0,Jwt,Single Page Application,Auth0,Auth0提供了描述身份验证最佳实践的广泛资源列表。其中有一系列建议,就是不要将localStorage用作平均存储(JWT)令牌 我发现这些观点存在一些问题: 有一种强烈的假设,即JWT令牌是攻击者不能访问的敏感信息(通过XSS) 从我的角度来看,访问令牌本身并不会扩大攻击范围。如果攻击者控制了受害者的浏览器,他们可以使用令牌从受影响的浏览器本身执行调用 访问令牌通常具有相当短的过期时间,并且可以通过浏览器固定,从而减少在XSS上下文之外使用它们的机会 Auth0建议从他们的S

Auth0提供了描述身份验证最佳实践的广泛资源列表。其中有一系列建议,就是不要将
localStorage
用作平均存储(JWT)令牌

我发现这些观点存在一些问题:

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

因此,我完全同意OWASP的建议,不要将敏感数据存储在
localStorage
,我永远不会想到在那里存储信用卡号码或密码,甚至个人数据。但这只是因为这些东西会让攻击者扩大攻击范围(访问银行帐户,尝试在其他应用程序中重用用户密码,等等)。但是我很难理解AccessToken是如何受到影响的。

尽管我对Auth0的实现、功能和设计决策知之甚少,但从我对OAuth2和安全性的总体理解来看,我可以尝试将这些点连接起来


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

让我们看一下你提出的要点

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

localstorage
的问题是:

  • localStorage
    sessionStorage
    不跨子域共享。这是SSO功能的最佳选择(有一些解决方案使用了
    iframe
    ,但这些解决方案看起来更像是解决办法,而不是一个好的解决方案。当使用响应标题X-Frame-Options来避免使用
    iframe
    的点击劫持攻击时,使用
    iframe
    的任何解决方案都是毫无疑问的)

  • XSS可以向攻击者控制的远程服务器发送访问和/或刷新令牌,从而允许攻击者模拟用户

  • 注意:第2点中提到的漏洞可以通过使用客户端必须证明其确实拥有令牌的方法来缓解。另一种选择是OWASP中提到的,它需要cookie。然而,Auth0似乎没有实现这些功能。因此,建议避免使用
    localstorage

    Auth0建议从他们的SDK中使用Auth0.getTokenSilently()来获取令牌,但据我所知,攻击者没有任何理由不能自己调用此方法

    对。这就是为什么

  • 我们首先需要通过以下方式来降低XSS的风险
  • 另外,
    getTokenSilently()
    方法要求在仪表板的API设置中启用
    允许跳过用户同意。虽然我没有看到关于这一点的具体指南,但我认为如果您将令牌存储在cookie中,则不需要启用此选项,从而消除滥用该方法的任何可能性
  • 我知道XSS无法访问令牌的唯一方法基本上是使用httpOnly Cookie,但这会自行创建新向量(CSRF),并且仍然无法阻止攻击者从受影响的浏览器中调用api

    对。但您可以通过以下一种或多种方法来缓解这一问题:

  • 使用
    SameSite
    cookie。参考文件。如果浏览器不支持
    SameSite
    cookie,请遵循下面的另一种方法
  • 状态变量(Auth0使用它)-客户端将生成一个加密强随机nonce,并随每个请求一起传递,服务器将随响应一起回显该nonce,从而允许客户端验证该nonce。这一点在本书中有解释
  • 使用具有加密强随机值的CSRF cookie,这样每个AJAX请求都会读取cookie值并将cookie值添加到自定义HTTP头中(GET和HEAD请求除外,它们不应该进行任何状态修改)。由于CSRF由于同源策略而无法读取任何内容,并且它基于利用不安全的HTTP方法(如POST、PUT和DELETE),因此此CSRF cookie将降低CSRF风险。所有现代SPA框架都使用这种使用CSRF cookie的方法。提到了角度法
  • 始终检查referer头并仅在referer是受信任域时接受请求。如果referer头不存在或是非白名单域,只需拒绝请求即可。当使用SSL/TLS时,通常会出现引用者。登录页(主要是信息性的,不包含登录表单