使用无状态(= Sessionless)身份validation时必需的CSRF令牌?

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

例:

  • 我们有一个单一的页面应用程序(否则我们必须在每个链接上添加标记: <a href="...?token=xyz">...</a>

  • 用户使用POST /authvalidation自己。 成功的身份validation服务器将返回一些令牌。

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

  • 这个令牌将被用来访问像/admin这样的受限制的URL。

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

  • 没有Http Session,也没有Cookies。

据我所知,应该(?!)不可能使用跨站点攻击,因为浏览器不会存储令牌,因此它不能自动发送到服务器(这就是使用Cookies /会议)。

我错过了什么吗?

我发现一些关于CSRF +的信息, 使用cookies进行authentication:

  1. https://auth0.com/blog/2014/01/07/angularjs-authentication-with-cookies-vs-token/
    “既然你不依赖于cookies,你不需要防止跨站请求”

  2. http://angular-tips.com/blog/2014/05/json-web-tokens-introduction/
    “如果我们按照cookies的方式,你真的需要做CSRF来避免跨站请求,这是我们可以忘记使用JWT时,你会看到。
    (JWT = Json Web Token,一个基于令牌的无状态应用程序authentication)

  3. http://www.jamesward.com/2013/05/13/securing-single-page-apps-and-rest-services
    “在不冒CSRF漏洞的情况下进行身份validation的最简单方法是简单地避免使用cookie来识别用户”

  4. http://sitr.us/2011/08/26/cookies-are-bad-for-you.html
    “CSRF最大的问题在于,cookies绝对不能防御这种攻击,如果你使用的是cookieauthentication,你还必须采取额外的措施来防止CSRF,最基本的防范措施就是确保你的应用程序从不会执行任何响应GET请求的副作用。“

如果您不使用Cookie进行身份validation,则有更多的页面说明您不需要任何CSRF保护。 当然,你仍然可以使用cookies来处理所有其他事情,但是不要把 session_id东西存储在里面。


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

  1. localStorage :浏览器内键值存储。 存储的数据即使在用户closures浏览器窗口后也可用。 数据不能被其他网站访问,因为每个网站都有自己的存储空间。

  2. sessionStorage :也是一个在浏览器中的数据存储。 区别在于:当用户closures浏览器窗口时,数据被删除。 但是,如果您的web应用程序由多个页面组成,它仍然很有用。 所以你可以做到以下几点:

    • 用户login后,将令牌存储在sessionStorage
    • 用户点击一个链接,加载一个新的页面(=一个真正的链接,没有JavaScript内容replace)
    • 您仍然可以从sessionStorage访问令牌
    • 要注销,您可以手动从sessionStorage删除令牌或等待用户closures浏览器窗口,这将清除所有存储的数据。

(对于这两个看看这里: http : //www.w3schools.com/html/html5_webstorage.asp )


有没有官方的标记身份validation标准?

JWT (Json Web Token):我认为这仍然是一个草案,但已经被很多人使用,这个概念看起来简单而安全。 (IETF: http : //tools.ietf.org/html/draft-ietf-oauth-json-web-token-25 )
也有很多的框架可用的库。 只是谷歌!

一个JWT,如果没有使用Cookies,就不需要CSRF令牌 – 但是! 通过将JWT存储在session / localStorage中,如果您的站点存在XSS漏洞(相当常见),则会暴露您的JWT和用户的身份。 向JWT添加csrfToken密钥并将JWT存储在具有securehttp-only属性的cookie中会更好。

请阅读这篇文章以获得更多信息https://stormpath.com/blog/where-to-store-your-jwts-cookies-vs-html5-web-storage

您可以通过包含xsrfToken JWT声明来使此CSRF保护无状态:

{ "iss": "http://galaxies.com", "exp": 1300819380, "scopes": ["explorer", "solar-harvester", "seller"], "sub": "tom@andromeda.com", "xsrfToken": "d9b9714c-7ac0-42e0-8696-2dae95dbc33e" }

因此,您需要将csrfToken存储在localStorage / sessionStorage以及JWT本身(存储在http-only和secure cookie中)中。 然后对于csrf保护,请validationJWT中的csrf标记与提交的csrf-token标头匹配。