CSRF 和 X-CSRF-Token 的区别 [英] Difference between CSRF and X-CSRF-Token

查看:67
本文介绍了CSRF 和 X-CSRF-Token 的区别的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  • 在 HTTP 标头中使用 X-CSRF-Tokentoken 有什么区别在隐藏的领域?
  • 何时使用隐藏字段,何时使用标题,为什么?
  • What is the difference between use X-CSRF-Token in an HTTP header or token in the hidden field?
  • When to use the hidden field and when to use the header and why?

我认为 X-CSRF-Token 是我使用 JavaScript/AJAX 但我不确定的时候.

I think that X-CSRF-Token is when I'm using JavaScript / AJAX but I'm not sure.

推荐答案

CSRF 保护有多种方法.

CSRF protection comes in a number of methods.

传统方式(同步器令牌"模式)通常涉及设置每个请求的唯一有效令牌值,然后在随后发送请求时验证该唯一值.通常通过设置隐藏表单字段来完成.令牌值通常是短暂的并且与该会话相关联,因此如果黑客试图重用他们之前在页面上看到的值,或者试图猜测值,他们可能会失败.因此,只有来自您的应用程序的请求才会起作用,而来自您的应用程序/域之外的伪造请求(即跨站点请求伪造)将失败.

The traditional way (the "Synchronizer token" pattern) usually involves setting a unique valid Token value for each request and then verifying that unique value when the request is subsequently sent in. It is usually done by setting a hidden form field. The token value is usually short lived and associated to that session, so if a hacker tries to reuse a value they saw previously on the page, or tries to guess the value they will likely fail. So only requests from your application will work and forged requests from outside your application/domain (aka cross site request forgery) will fail.

这样做的缺点是它要求您的应用程序在所有 HTML 表单上设置此隐藏标记.这些页面现在必须由应用程序动态生成,而以前它们可能是静态 HTML.它还可以破坏后退按钮(因为您需要刷新表单以重新生成另一个唯一的 CSRF 值).您现在还需要跟踪服务器端的有效令牌并检查任何使用有效令牌的请求.这可能需要付出相当多的额外努力来实施和保持前进.

The downside of that is it requires your application to set this hidden token on all HTML forms. These pages now have to be dynamically generated by an application, when perhaps previously they were static HTML. It can also break the back button (as you need to refresh the form to regenerate another unique CSRF value). You also now need to keep track of valid tokens on the server side and check any requests use a valid token. This can take quite a bit of extra effort to implement and maintain going forward.

另一种方法(称为 Cookie-to-header 令牌"模式)是为每个会话设置一次 Cookie,并让 JavaScript 读取该 cookie 并设置自定义 HTTP 标头(通常称为 X-CSRF-TOKENX-XSRF-TOKEN 或只是 XSRF-TOKEN) 具有该值.任何请求都将发送标头(由 Javascript 设置)和 cookie(由浏览器设置为标准 HTTP 标头),然后服务器可以检查 X-CSRF-TOKEN 标头中的值是否匹配cookie 标头中的值.想法是只有在同一域上运行的 JavaScript 才能访问 cookie,因此来自另一个域的 JavaScript 无法将此标头设置为正确的值(假设该页面不易受到 XSS 的攻击,从而可以访问此 cookie).即使是假链接(例如在钓鱼邮件中)也不起作用,因为即使它们看起来来自正确的域,也只会设置 cookie 而不会设置 X-CSRF-TOKEN 标头.

An alternative approach (called the "Cookie-to-header token" pattern) is to set a Cookie once per session and the have JavaScript read that cookie and set a custom HTTP header (often called X-CSRF-TOKEN or X-XSRF-TOKEN or just XSRF-TOKEN) with that value. Any requests will send both the header (set by Javascript) and the cookie (set by the browser as a standard HTTP header) and then the server can check that value in the X-CSRF-TOKEN header matches the value in the cookie header. The idea being that only JavaScript run on the same domain would have access to the cookie, so JavaScript from another domain couldn't set this header to the right value (assuming the page is not vulnerable to XSS that would give access to this cookie). Even fake links (e.g. in a phishing email) would not work either, as even though they would appear to come from the right domain, only the cookie will be set but not X-CSRF-TOKEN header.

这可能比同步器令牌模式更容易实现,因为您不需要为每个表单的每次调用设置令牌,并且检查也相对简单(只需检查 cookie 与标头匹配)而不是跟踪 CSRF 令牌的有效性.您只需为每个会话设置一个随机值的 cookie.如果看到 cookie,一些前端框架甚至会自动为您生成标头(例如 AngularJS 这样做 例如).

This can be MUCH easier to implement than the Synchronizer token pattern as you don't need to set the token for each call to each form, and the check is relatively simple too (just check the cookie matches the header) rather than tracking CSRF tokens validity. All you need is to set a cookie to a random value for each session. Some front end frameworks will even automatically generate the header for you if they see the cookie (e.g. AngularJS does this for example).

缺点是它需要 JavaScript 才能工作(但如果您的应用在没有 JavaScript 的情况下基本上无法工作,这可能不是问题)而且它仅适用于 JavaScript 发出的请求(例如 XHR 请求) - 常规HTML 表单请求不会设置标题.对此的一个变体("Double Submit Cookie" 模式)将 X-CSRF-TOKEN 值在隐藏的表单字段中而不是在 HTTP 标头中来解决这个问题,但仍然保持服务器端逻辑比传统的同步器令牌模式更简单.但是应该注意 OWASP 声明了一些Double Submit 方法的弱点,当攻击者能够设置 cookie(这通常比读取 cookie 更容易)时,建议在这种情况下验证 CSRF 令牌.

The downside is that it requires JavaScript to work (but that may not be an issue if your app basically doesn't work without JavaScript anyway) and also it will only work for requests the JavaScript makes (e.g. XHR requests) - regular HTML form requests would not set the header. A variation on this (the "Double Submit Cookie" pattern) puts the X-CSRF-TOKEN value in a hidden form field rather than in an HTTP Header to get around this but still keep the server side logic simpler than the traditional Synchronizer token pattern. It should be noted however that OWASP states some weaknesses with the Double Submit method, when the attacker is able to set the cookie (which is often easier than reading the cookie) so recommends validating the CSRF token in this case.

此外,同步器令牌模式可以允许额外的控制来强制执行流程(例如,隐藏字段 CSRF 令牌只会在应用程序认为您已发送有效请求以获取该表单时设置).

Additionally the Synchronizer token pattern can allow extra controls to enforce flow (e.g. the hidden field CSRF token will only be set when the application thinks you have sent a valid request in to get that form).

哦,一些安全扫描会发现 cookie 没有设置 HTTP-Only 标志,因此可以被 JavaScript 读取 - 但这是故意的,因为它需要能够读取那!虚假警报.您可能会认为,只要您使用像 X-CSRF-TOKEN 这样的通用名称,他们就会知道不标记这个,但经常看到它被标记.

Oh and some security scans will pick up the fact the cookie is not set with the HTTP-Only flag so can be read by JavaScript - but that's deliberate as it needs to be able to read by that! False alert. You'd think as long as you are using a common name like X-CSRF-TOKEN they would know not to flag this, but have seen it flagged often.

这篇关于CSRF 和 X-CSRF-Token 的区别的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆