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