是否可以在没有同源策略的情况下保护 JSON API 免受 CSRF 攻击?



是否有必要同源来防止CSRF(我知道这还不够(? 或者可以在没有任何同源策略的情况下完成?这适用于客户端呈现的应用程序,我无法在页面上的元素中隐藏令牌。

下面是CSRF攻击的典型示例:

  1. 登录到银行网站,现在您有一个会话cookie来保持登录状态。
  2. 您访问一个恶意站点,该站点向/transfer_funds发送 POST 请求。
  3. 这些 Cookie 与 POST 请求一起发送。
  4. 请求已通过身份验证,现在您的钱已发送给攻击者。

现在,让我们看看每一步,看看如何预防它们。

第 1 步可以通过没有登录 cookie 来阻止,但这非常不方便且不切实际。

第 2 步可以通过非常小心您访问的网站来防止,但这也非常不方便,您无法保证您的用户这样做。您可能认为 CORS 策略可能会有所帮助,但事实并非如此,因为有多种方法可以绕过它。fetchAPI 具有忽略 CORS 标头的no-cors模式,并且只是不使响应可用,但在这种情况下,攻击者不关心响应,只关心请求。此外,另一个常见的事情是使用 javascript 填写表单,然后使用 javascript 提交表单,也绕过 CORS。

可以使用 cookie 的SameSite属性绕过第 3 步,特别是LaxStrict。对于Lax,cookie 仅在第三方请求时发送,如果它是 GET 请求,并且您的网站应该设计为没有 GET 请求可以做任何坏事。对于Strict,第三方网站根本无法发送cookie,这意味着他们甚至无法利用GET请求。这可能是最好的解决方案,大多数浏览器默认使用SameSite=Lax,这意味着CSRF不是一个主要问题。如果您想确保您的用户安全,您可以在 Cookie 上明确设置SameSite=LaxSameSite=Strict

使用经典的 CSRF 令牌 + CORS 可以防止第 4 步,这要求攻击者发出 GET 请求以获取 CSRF 令牌,然后才能发出 POST 请求。但是,由于他们现在实际上需要响应,因此no-cors不起作用,并且无法以您的身份进行身份验证。

另外,作为旁注,如果你根本没有cookie,那么CSRF不是问题。

是的,但有开销。

成功登录后颁发令牌。由于您没有在页面上来回传递它,因此有必要在服务器上使用一些后端存储(例如会话状态(将其与登录用户的会话相关联。这是开销。

现在,每次调用可以更改状态的 API 都必须包含令牌,例如在标头中。令牌可以缓存在客户端上。没有令牌,无法访问任何更改状态的内容。

恭喜,您已经击败了 CSRF 攻击。您仍然需要处理所有常见的管理方面,例如令牌过期、令牌续订等。

最新更新