反CSRF代币如何在SPA-API通信中工作



最近我在学习Web安全的一些基础知识,但有些东西我无法理解。反CSRF代币如何在SPA-API通信中工作?

据我所知,反CSRF用于SPA-API通信,如下所示;

  1. 浏览器向API发送登录请求
  2. API服务器生成一个令牌并将其发送回浏览器
  3. 浏览器存储它,当浏览器发出下一个请求时,令牌将与一起发送
  4. API可以确保请求来自真正的前端,因为它包含令牌

我突然想到一个问题——它如何预防CSRF?如果令牌存储在cookie中,则每当请求发生时,它将自动发送到API,就像通常的会话cookie一样。即使它存储在其他存储中(如会话存储或本地存储(,也可以使用JavaScript进行访问。

因此,一旦用户被攻击者的网站吸引,反CSRF代币就完全无用了。

最重要的是,我不明白反CSRF令牌和身份验证/授权中使用的常见cookie之间有什么区别……

也许我对反CSRF令牌的工作方式产生了严重的误解。请指出它出了什么问题。

当攻击者可以使用经过身份验证的用户的cookie向端点提交请求时,就会存在最常见的CSRF漏洞之一。如果您不使用cookie(即验证用户的请求(或其他自动验证技术(如HTTP基本验证(,则通常不需要CSRF令牌。

示例#1

假设您使用的是REST API,它依赖于访问令牌或承载令牌进行身份验证。此令牌通常在HTTP授权标头(而不是cookie(中提交。在这种情况下,只要身份验证不是自动的(例如,使用cookie(,就不需要CSRF令牌。

示例#2

在这种情况下,假设浏览器确实将会话cookie发送到web服务/API以验证请求。那么,是的,如果不实施反CSRF控制,你将很容易受到CSRF的影响。防止这种情况的一种方法是在加载SPA时向浏览器提供反CSRF令牌。然后,浏览器可以将该令牌与请求一起发送到端点。然后,当收到请求时,web服务必须验证该令牌。

这种验证可以通过多种方式进行。这可以使用双重提交cookie、cookie到标头令牌、加密技术,甚至共享数据库来完成。

使用反CSRF令牌

反CSRF代币通常应而不是存储在cookie中。如OWASP CSRF预防作弊表所述:

<meta>标签中可以包含CSRF令牌。所有后续呼叫可以从该CCD_ 2标签中提取CSRF令牌。它可以也可以存储在JavaScript变量中或DOM上的任何位置。但是,不建议将其存储在cookie或本地浏览器中存储

例如,反CSRF令牌可能会嵌入页面中,如下所示:

<meta name="csrf-token" content="{{ csrf_token() }}">

其中csrf_token()调用一些将令牌嵌入标记中的服务器端函数。

然后可以使用在JavaScript中读取

let csrf_token = document.querySelector("meta[name='csrf-token']").getAttribute("content");

然后在做出API请求时(例如,在POST请求中的X-CSRF-Token报头中(发送到服务器。此外,令牌对于会话应该是唯一的。

然而,即使令牌要存储在cookie中,也可以使用HttpOnly标头设置cookie。这样可以防止JavaScript读取cookie。这在减轻跨站点脚本(XSS(攻击方面更为有用。

附加信息

  • 这个StackExchange安全问题包含了许多关于在RESTAPI中使用CSRF保护的好信息

关于CSRF的其他良好资源:

  • https://portswigger.net/web-security/csrf
  • https://owasp.org/www-community/attacks/csrf

最新更新