首页 文章

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

提问于
浏览
99

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

例:

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

  • 用户使用 POST /auth 验证自己 . 成功验证后,服务器将返回一些令牌 .

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

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

  • 令牌将始终在HTTP标头内传输 .

  • 没有Http Session,也没有Cookies .

据我了解,应该(?!)不可能使用跨站点攻击,因为浏览器不会存储令牌,因此它无法自动将其发送到服务器(这就是使用Cookies时会发生的情况/ Session ) .

我错过了什么吗?

2 回答

  • 134

    TL; DR

    如果在没有Cookie的情况下使用JWT,则无需使用CSRF令牌 - 但是!通过在会话/ localStorage中存储JWT,如果您的站点存在XSS漏洞(相当常见),则会暴露您的JWT和用户身份 . 最好将一个 csrfToken 键添加到JWT并将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” ,“卖方”],“sub”:“tom@andromeda.com”,“xsrfToken”:“d9b9714c-7ac0-42e0-8696-2dae95dbc33e”}

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

  • 44

    我发现了一些有关CSRF的信息,使用 no cookie进行身份验证:

    还有更多页面,表明您没有使用cookie进行身份验证 . 当然你仍然可以在其他所有内容中使用cookie,但 avoid 在其中存储了类似 session_id 的内容 .


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

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

    • sessionStorage :也是浏览器数据存储中的一个 . 不同之处在于:当用户关闭浏览器窗口时,数据将被删除 . 但是,如果您的webapp由多个页面组成,它仍然很有用 . 所以你可以做到以下几点:

    • 用户登录,然后将令牌存储在 sessionStorage

    • 用户点击链接,该链接加载新页面(=真实链接,没有javascript内容替换)

    • 您仍然可以从 sessionStorage 访问令牌

    • 要注销,您可以手动从 sessionStorage 删除令牌,或者等待用户关闭浏览器窗口,这将清除所有存储的数据 .

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


    令牌身份验证是否有官方标准?

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

相关问题