使用JSON Web令牌进行CSRF保护

Jul*_*enD 45 csrf local-storage jwt auth0

我读到在使用JWT时,没有必要防止CRSF攻击,例如:" 因为你不依赖于cookie,所以你不需要防止跨站点请求 ".

但是,我不明白:如果我将令牌存储在localStorage中(正如我在同一网站的教程中所建议的那样),是什么阻止攻击者通过读取我的localStorage而不是我的cookie来伪造恶意请求?

由于它是在服务器端生成的,因此我不知道如何在客户端请求中使用令牌而不将其存储在客户端的某个位置.

kup*_*fic 101

严格地说,是的,存储在本地/会话存储中的任何东西(我称之为HTML5存储)都可能在跨站点脚本(XSS)攻击中被盗.看到这篇文章.

但是,有许多可动部件需要考虑.

首先,HTML5存储和cookie在JavaScript访问方面的作用方式存在细微差别.

HTML5存储是:

  • 分为http和https.http://example.com运行的JavaScript无法访问存储在HTML5存储中的项目https://example.com.
  • 在子域之间划分.http://example.com运行的JavaScript无法访问存储在HTML5存储中的项目http://sub.example.com(但是,您可以通过一些技巧来解决此问题).

饼干更松散 - 鹅毛:

  • 具有域的cookie example.com将转到两者http://example.com,https://example.com 除非它具有该属性secure,在这种情况下它将仅发送到https.
  • 未使用显式域发送的cookie只会发送回发送它的确切域.如果明确定义了域example.com,那么它将被发送到example.comsub.example.com.(不幸的是,这是cookie"spec"中最令人困惑的部分,请参阅本文).
  • 如果cookie在具有匹配域的页面上运行(并且尊重securecookie标志),则可以通过JavaScript读取cookie,除非 cookie具有该httpOnly属性,在这种情况下JavaScript将无法读取它.

其次,由于cookie被标记为域,因此当向服务器发出请求时,浏览器将发送具有匹配域的全有cookie,而不管发起请求的页面的域是什么.

最后一部分是如何完成CSRF攻击(同源策略只能帮助很多).CSRF上OWASP页面是学习这些攻击如何工作的良好资源.

将身份验证令牌存储在本地存储中并手动将其添加到每个请求的原因可以防止CSRF关键字:手动.由于浏览器没有自动发送该身份验证令牌,如果我访问evil.com它并设法发送一个POST http://example.com/delete-my-account,它将无法发送我的authn令牌,因此请求被忽略.

考虑到上述因素,无论是使用cookie还是HTML5存储都会成为一系列权衡因素:

将身份验证令牌存储在HTML5存储中意味着:

  • (-) 在XSS攻击中被盗的风险.
  • (+) 提供CSRF保护.
  • (-) 必须手动修改发往服务器的每个请求,限制您使用SPA(例如AngularJs)Web应用程序.

在另一方面,如果存储在标记一个cookie的authn令牌httpOnly secure,则:

  • (+) XSS无法窃取authn令牌.
  • (-)您必须自己提供CSRF保护.在某些框架中实施CSRF保护比其他框架更容易.

哪个选项更好取决于您的需求.

  • 你的authn令牌是否保护任何与钱有关的东西?你可能想要cookie httpOnly secure选项.
  • 实施CSRF保护所需的工作量是否值得保护它的资产?那么HTML5存储可能是正确的位置.

  • 很棒的答案.我现在比以往任何时候都更害怕.是时候仔细检查我的应用中的每个文本输入字段. (3认同)
  • @Zack在evil.com上运行的JavaScript如何访问example.com的网络存储?这不可以。Web存储规范讨论了为什么每个域的Web存储都必须是私有的,https://www.w3.org/TR/webstorage/#implementation-risks。我不明白您说的是什么:“ WebStorage会愉快地通过HTTP发送流量”,Web存储不会发送或接收http请求。与我的原始答案类似,这是一篇有关使用网络存储来存储会话Cookie的文章,http://blog.portswigger.net/2016/05/web-storage-lesser-evil-for-session.html (3认同)
  • 首先,同源可以防止读取/查看数据,但不能防止提交请求。如果错了请纠正我。 (2认同)
  • @Zack evil.com无法访问example.com的网络存储或cookie,因此evil.com无法获得有效的身份验证/ CSRF令牌.但是,即使从evil.com发送cookie,cookie也会自动提交给服务器以获取所有请求.如果您的会话令牌是cookie,您还需要提供CSRF令牌.但是,如果您的会话令牌位于本地存储中,则必须"手动"将其添加到每个请求中,浏览器不会为您执行此操作.如果Javascript将令牌添加为自定义标头,那将更好,因为SOP不允许使用自定义标头的跨源请求. (2认同)

sen*_*vic 7

使用基于令牌的身份验证时,您必须手动将令牌与请求关联。与 cookie 不同,令牌不是由浏览器自动设置的,因此不易受到csrf攻击。

虽然这种方法不会受到csrf攻击,但也容易受到xss攻击。

最小的改进是使用session storage而不是local storage因为session storage用户关闭选项卡/浏览器后数据会被清除。