Authentication 使用无状态(=无会话)身份验证时是否需要CSRF令牌?

Authentication 使用无状态(=无会话)身份验证时是否需要CSRF令牌?,authentication,csrf,single-page-application,stateless,csrf-protection,Authentication,Csrf,Single Page Application,Stateless,Csrf Protection,当应用程序依赖于无状态身份验证(使用类似HMAC的东西)时,是否有必要使用CSRF保护 例如: 我们有一个单页应用程序(否则我们必须在每个链接上附加令牌:) 用户使用POST/auth对自己进行身份验证。身份验证成功后,服务器将返回一些令牌 令牌将通过JavaScript存储在单页应用程序中的某个变量中 此令牌将用于访问受限制的URL,如/admin 令牌将始终在HTTP头中传输 没有Http会话,也没有Cookie 据我所知,应该不可能使用跨站点攻击,因为浏览器不会存储令牌,因此它无法自动

当应用程序依赖于无状态身份验证(使用类似HMAC的东西)时,是否有必要使用CSRF保护

例如:

  • 我们有一个单页应用程序(否则我们必须在每个链接上附加令牌:

  • 用户使用
    POST/auth
    对自己进行身份验证。身份验证成功后,服务器将返回一些令牌

  • 令牌将通过JavaScript存储在单页应用程序中的某个变量中

  • 此令牌将用于访问受限制的URL,如
    /admin

  • 令牌将始终在HTTP头中传输

  • 没有Http会话,也没有Cookie

据我所知,应该不可能使用跨站点攻击,因为浏览器不会存储令牌,因此它无法自动将令牌发送到服务器(使用cookie/会话时会发生这种情况)


我遗漏了什么吗?

我发现了一些关于CSRF+的信息,使用cookies进行身份验证:


  • “由于您不依赖Cookie,因此不需要防止跨站点请求”


  • “如果我们采用cookies方式,您确实需要进行CSRF以避免跨站点请求。正如您将看到的,在使用JWT时,我们可能会忘记这一点。”
    (JWT=Json Web令牌,一种针对无状态应用程序的基于令牌的身份验证)


  • “在不冒CSRF漏洞风险的情况下进行身份验证的最简单方法是避免使用cookie识别用户”


  • “CSRF的最大问题是cookie绝对无法抵御此类攻击。如果您使用cookie身份验证,您还必须采取其他措施来防范CSRF。您可以采取的最基本的预防措施是确保您的应用程序不会对GET reque执行任何副作用sts。”

  • 如果不使用Cookie进行身份验证,还有很多页面说明您不需要任何CSRF保护。当然,您仍然可以将Cookie用于其他所有内容,但避免在其中存储任何类似
    会话id的内容


    如果需要记住用户,有两个选项:

  • localStorage
    :浏览器中的键值存储。即使用户关闭浏览器窗口,存储的数据仍然可用。其他网站无法访问这些数据,因为每个网站都有自己的存储

  • 会话存储
    :也是一个浏览器内数据存储。区别在于:当用户关闭浏览器窗口时,数据会被删除。但是,如果您的Web应用程序包含多个页面,它仍然很有用。因此,您可以执行以下操作:

    • 用户登录,然后将令牌存储在
      sessionStorage
    • 用户单击一个链接,加载一个新页面(=一个真正的链接,没有javascript内容替换)
    • 您仍然可以从
      sessionStorage
    • 要注销,您可以从
      sessionStorage
      手动删除令牌,或者等待用户关闭浏览器窗口,这将清除所有存储的数据
  • (两人都可以在此处查看:)


    代币认证是否有任何官方标准

    JWT(Json Web令牌):我认为它仍然是一个草稿,但它已经被许多人使用,而且这个概念看起来简单而安全。(IETF:)
    还有很多可用的框架库。只需谷歌就可以了!

    TL;DR

    如果使用JWT时没有cookie,则无需使用CSRF令牌-但是!如果您的站点存在XSS漏洞(相当常见),则通过将JWT存储在会话/本地存储中,您可以公开您的JWT和用户身份。最好向JWT添加
    csrfToken
    密钥,并将JWT存储在设置了
    secure
    http only
    属性的cookie中

    阅读这篇文章,了解更多信息

    通过包含xsrfToken JWT声明,可以使此CSRF保护成为无状态:

    {
    “国际空间站”:http://galaxies.com",
    “经验”:1300819380,
    “范围”:[“探索者”、“太阳能收割机”、“卖方”],
    “分包商”:tom@andromeda.com",
    “xsrfToken”:“d9b9714c-7ac0-42e0-8696-2dae95dbc33e”
    }


    因此,您需要将csrfToken存储在localStorage/sessionStorage以及JWT本身(存储在仅http的安全cookie中)中。然后,对于csrf保护,请验证JWT中的csrf令牌是否与提交的csrf令牌头匹配。

    请注意基本身份验证。许多浏览器将在会话的其余部分自动发送基本身份验证头。这会使基本身份验证与cookie身份验证一样容易受到csrf的攻击。csrf的精彩总结!我将注意存储您的令牌localStorage或sessionStorage中的易受XSS攻击,并且可以通过页面上的脚本查看数据-因此,如果您有CDN提供的受损脚本,或者某个JS库中存在恶意代码,他们可以从这些存储位置窃取令牌。请参阅:我认为最安全的方法是存储JWT+CSRF令牌,然后将计算出的JWT和CSRF令牌放在请求头中。关于:“您可以采取的最基本预防措施是确保应用程序在响应GET请求时不会产生任何副作用。”CSRF攻击是否可能伪造POST请求?这取决于服务器端应用程序。有些Web框架使用类似
    http://.../someRestResource?method=POST
    。因此它基本上是一个
    GET
    请求,但服务器应用程序将其解释为
    POST
    请求,因为它被配置为使用
    方法