CSRF 和 X-CSRF-Token 之间的区别
Difference between CSRF and X-CSRF-Token
- 在 HTTP header 或 令牌中使用
X-CSRF-Token
有什么区别
在隐藏字段中?
- 何时使用隐藏字段以及何时使用 header 为什么?
我认为 X-CSRF-Token
是当我使用 JavaScript / AJAX 但我不确定。
CSRF 保护有多种方法。
传统方式(the "Synchronizer token" pattern)通常是为每个请求设置一个唯一有效的Token值,然后在后续发送请求时验证该唯一值。通常通过设置一个隐藏的表单字段来完成.令牌值通常是短暂的并与 session 相关联,因此如果黑客试图重用他们之前在页面上看到的值,或者试图猜测该值,他们很可能会失败。因此,只有来自您的应用程序的请求才能工作,而来自您 application/domain 外部的伪造请求(也称为跨站点请求伪造)将失败。
缺点是它要求您的应用程序在所有 HTML 表单上设置此隐藏令牌。这些页面现在必须由应用程序动态生成,而以前它们可能是静态的 HTML。它还可以破坏后退按钮(因为您需要刷新表单以重新生成另一个唯一的 CSRF 值)。您现在还需要在服务器端跟踪有效令牌并检查所有请求是否使用有效令牌。这可能需要相当多的额外努力来实施和维护。
另一种方法(称为 the "Cookie-to-header token" pattern)是为每个 session 设置一次 Cookie,让 JavaScript 读取该 cookie 并设置自定义 HTTP header(通常使用该值称为 X-CSRF-TOKEN
或 X-XSRF-TOKEN
或 XSRF-TOKEN
)。任何请求都会发送 header(由 Javascript 设置)和 cookie(由浏览器设置为标准 HTTP header),然后服务器可以检查 X-CSRF-TOKEN
header 匹配 cookie header 中的值。这个想法是只有同一域中的 JavaScript 运行 才能访问 cookie,因此来自另一个域的 JavaScript 无法将此 header 设置为正确的值(假设该页面不易受到可以访问此 cookie 的 XSS 攻击)。即使是虚假链接(例如在网络钓鱼电子邮件中)也不会起作用,因为即使它们看起来来自正确的域,也只会设置 cookie 而不是 X-CSRF-TOKEN
header.
这比 Synchronizer 令牌模式更容易实现,因为您不需要为每个表单的每次调用设置令牌,而且检查也相对简单(只需检查 cookie 与 header) 而不是跟踪 CSRF 令牌的有效性。您只需要为每个 session 设置一个随机值的 cookie。如果某些前端框架看到 cookie,甚至会自动为您生成 header(例如 AngularJS does this)。
缺点是它需要 JavaScript 才能工作(但如果您的应用在没有 JavaScript 的情况下基本上无法工作,这可能不是问题),而且它仅适用于请求JavaScript 发出(例如 XHR 请求)- 常规 HTML 表单请求不会设置 header。对此的一种变体("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,当攻击者能够设置 cookie(这通常比读取 cookie 更容易)时,建议在这种情况下验证 CSRF 令牌。
此外,Synchronizer 令牌模式可以允许额外的控制来强制执行流程(例如,仅当应用程序认为您已发送有效请求以获取该表单时,才会设置隐藏字段 CSRF 令牌)。
哦,一些安全扫描会发现 cookie 没有设置 HTTP-Only
标志,因此可以被 JavaScript 读取 - 但这是故意的,因为它需要能够读取通过那个!错误警报。你会认为只要你使用像 X-CSRF-TOKEN
这样的通用名称,他们就会知道不要标记它,但看到它经常被标记。
所有这些都是为了防止跨站请求伪造,你只需要使用其中一个向后端发送请求。不同的名称来自不同的框架。
都是关于向后端发送 csrf value
。然后后端会将其与存储在该特定用户的数据库中的 csrf 值进行比较。
csrf:
- 用于HTML形式(不是AJAX)
- 在呈现 HTML 表单时在后端生成。
- 我们无法直接在HTML表单中设置请求header,所以我们必须通过表单输入将其作为隐藏字段发送。
- 你可以随意命名这个隐藏的输入。
例如:<input name="my_csrf_input" value="a_hashed_string(the csrf value)"
X-CSRF-TOKEN:
- 它被添加到请求 HTTP header 用于 AJAX 请求。
- 要使用它,我们可以在渲染 HTML 的同时将
csrf value
放在 <meta>
标签中,然后在前端我们可以从 <meta>
中获取值] 标记并发送到后端。
Laravel具体:
- 当使用 Laravel 作为后端时。 Laravel 自动检查此 header 并将其与数据库中的有效
csrf value
进行比较(Laravel 为此有一个中间件)。
X-XSRF-TOKEN:
- 它被添加到 header 请求中 AJAX 请求。
- 像 Angular and Axios 这样的热门库会自动从
XSRF-TOKEN
cookie 中获取此 header 的值并将其放入每个请求 header.
- 要使用它,我们应该在后端创建一个名为
XSRF-TOKEN
的cookie,然后我们使用Angular或axios的前端框架将使用它自动。
Laravel具体:
- 因为它很受欢迎,Laravel 在每个响应中创建此 cookie。
- 所以当您使用 Axios 和 Laravel 时,您不需要做任何事情,只需登录用户,'auth' 中间件就会完成这项工作。
- 与
X-CSRF-Token
相比,这是一个更大的字符串,因为 cookie 在 Laravel 中加密。
- 在 HTTP header 或 令牌中使用
X-CSRF-Token
有什么区别 在隐藏字段中? - 何时使用隐藏字段以及何时使用 header 为什么?
我认为 X-CSRF-Token
是当我使用 JavaScript / AJAX 但我不确定。
CSRF 保护有多种方法。
传统方式(the "Synchronizer token" pattern)通常是为每个请求设置一个唯一有效的Token值,然后在后续发送请求时验证该唯一值。通常通过设置一个隐藏的表单字段来完成.令牌值通常是短暂的并与 session 相关联,因此如果黑客试图重用他们之前在页面上看到的值,或者试图猜测该值,他们很可能会失败。因此,只有来自您的应用程序的请求才能工作,而来自您 application/domain 外部的伪造请求(也称为跨站点请求伪造)将失败。
缺点是它要求您的应用程序在所有 HTML 表单上设置此隐藏令牌。这些页面现在必须由应用程序动态生成,而以前它们可能是静态的 HTML。它还可以破坏后退按钮(因为您需要刷新表单以重新生成另一个唯一的 CSRF 值)。您现在还需要在服务器端跟踪有效令牌并检查所有请求是否使用有效令牌。这可能需要相当多的额外努力来实施和维护。
另一种方法(称为 the "Cookie-to-header token" pattern)是为每个 session 设置一次 Cookie,让 JavaScript 读取该 cookie 并设置自定义 HTTP header(通常使用该值称为 X-CSRF-TOKEN
或 X-XSRF-TOKEN
或 XSRF-TOKEN
)。任何请求都会发送 header(由 Javascript 设置)和 cookie(由浏览器设置为标准 HTTP header),然后服务器可以检查 X-CSRF-TOKEN
header 匹配 cookie header 中的值。这个想法是只有同一域中的 JavaScript 运行 才能访问 cookie,因此来自另一个域的 JavaScript 无法将此 header 设置为正确的值(假设该页面不易受到可以访问此 cookie 的 XSS 攻击)。即使是虚假链接(例如在网络钓鱼电子邮件中)也不会起作用,因为即使它们看起来来自正确的域,也只会设置 cookie 而不是 X-CSRF-TOKEN
header.
这比 Synchronizer 令牌模式更容易实现,因为您不需要为每个表单的每次调用设置令牌,而且检查也相对简单(只需检查 cookie 与 header) 而不是跟踪 CSRF 令牌的有效性。您只需要为每个 session 设置一个随机值的 cookie。如果某些前端框架看到 cookie,甚至会自动为您生成 header(例如 AngularJS does this)。
缺点是它需要 JavaScript 才能工作(但如果您的应用在没有 JavaScript 的情况下基本上无法工作,这可能不是问题),而且它仅适用于请求JavaScript 发出(例如 XHR 请求)- 常规 HTML 表单请求不会设置 header。对此的一种变体("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,当攻击者能够设置 cookie(这通常比读取 cookie 更容易)时,建议在这种情况下验证 CSRF 令牌。
此外,Synchronizer 令牌模式可以允许额外的控制来强制执行流程(例如,仅当应用程序认为您已发送有效请求以获取该表单时,才会设置隐藏字段 CSRF 令牌)。
哦,一些安全扫描会发现 cookie 没有设置 HTTP-Only
标志,因此可以被 JavaScript 读取 - 但这是故意的,因为它需要能够读取通过那个!错误警报。你会认为只要你使用像 X-CSRF-TOKEN
这样的通用名称,他们就会知道不要标记它,但看到它经常被标记。
所有这些都是为了防止跨站请求伪造,你只需要使用其中一个向后端发送请求。不同的名称来自不同的框架。
都是关于向后端发送 csrf value
。然后后端会将其与存储在该特定用户的数据库中的 csrf 值进行比较。
csrf:
- 用于HTML形式(不是AJAX)
- 在呈现 HTML 表单时在后端生成。
- 我们无法直接在HTML表单中设置请求header,所以我们必须通过表单输入将其作为隐藏字段发送。
- 你可以随意命名这个隐藏的输入。
例如:<input name="my_csrf_input" value="a_hashed_string(the csrf value)"
X-CSRF-TOKEN:
- 它被添加到请求 HTTP header 用于 AJAX 请求。
- 要使用它,我们可以在渲染 HTML 的同时将
csrf value
放在<meta>
标签中,然后在前端我们可以从<meta>
中获取值] 标记并发送到后端。
Laravel具体:
- 当使用 Laravel 作为后端时。 Laravel 自动检查此 header 并将其与数据库中的有效
csrf value
进行比较(Laravel 为此有一个中间件)。
X-XSRF-TOKEN:
- 它被添加到 header 请求中 AJAX 请求。
- 像 Angular and Axios 这样的热门库会自动从
XSRF-TOKEN
cookie 中获取此 header 的值并将其放入每个请求 header. - 要使用它,我们应该在后端创建一个名为
XSRF-TOKEN
的cookie,然后我们使用Angular或axios的前端框架将使用它自动。
Laravel具体:
- 因为它很受欢迎,Laravel 在每个响应中创建此 cookie。
- 所以当您使用 Axios 和 Laravel 时,您不需要做任何事情,只需登录用户,'auth' 中间件就会完成这项工作。
- 与
X-CSRF-Token
相比,这是一个更大的字符串,因为 cookie 在 Laravel 中加密。