切换语言为:繁体

通俗讲一下CSRF攻击

  • 爱糖宝
  • 2024-10-20
  • 2033
  • 0
  • 0

什么是CSRF??

大家都听过一句话叫“陌生的链接不要乱点”,原因就是钓鱼网站的链接点开之后会造成CSRF攻击。 CSRF译为“跨站请求伪造”。简单来说就是钓鱼网站链接盗用了用户的信息(例如银行网站颁发给用户的token),执行了非用户本意的操作(如转账交易)。

举个例子

a用户是某bank的用户,在a登录bank.com时,bank.com会设置响应头

Set-Cookie: token=abcdefg;

以后a用户再访问bank.com时会在请求头中自动携带该cookie。

这时a用户点击了danger.com时,danger.com会响应一个页面,页面中可能包含以下元素

<img src="https://bank.com/pay?payuser=dangeruser&money=10000" />

虽然danger.com拿不到a用户在bank.com的cookie,但<img/>元素会向bank.com发送请求,发送请求就会携带cookie,而cookie中就包含用户信息(token),bank.com收到该请求,并验证该用户的token正确后,就会正常响应这个转账请求

<img/>元素与ajax不同,不受到浏览器同源策略中跨域的影响,可以正常发送请求

常见的CSRF攻击防范手段

1.直接不使用cookie

不使用cookie行不行呢?肯定是可以,毕竟有localstorage嘛。但cookie的兼容性比localstorage要好,很多大厂的网站依旧使用cookie。

并且cookie对ssr的场景较友好,因为服务端渲染中,构建页面的地方在服务端。假设用户已经登陆过a.com。那么下次输入url请求a.com时,自动携带cookie。a.com就能自动推荐该用户喜欢的内容。而假设没有使用cookie而是localstorage。用户在请求a.com时,就不能自动携带localstorage中的用户信息,因为localstorage需要js来手动加到请求中。

2.使用SameSite

SameSite是近几年新出的一个属性,用于增强cookie的安全性,但兼容性较差,用法如下。

Set-Cookie: token=abcdefg;SameSite=Lax;

SameSite有两个取值

SameSite=Strict

这种设置下,浏览器只会在当前请求源和 cookie 设置的源相同时才发送 cookie。即使用户从别的站点点击了一个链接,跳转到当前站点,cookie 也不会被发送。

还是刚才那个例子,由于用户登录bank.com后bank.com响应的Set-Cookie中SameSite=Strict

Set-Cookie: token=abcdefg;SameSite=Strict;

即使danger.com中嵌入了

<img src="https://bank.com/pay?payuser=dangeruser&money=10000" />

由于 SameSite=Strict 的存在,danger.com与bank.com的源不一样,cookie则不会携带过去。即使bank.com能收到转账请求,但由于没有cookie中的token,则验证失败,拒绝转账请求。

它提供了最高级别的安全性,但也会影响到一些正当的跨站点请求。

SameSite=Lax

Lax译为宽松的、不严格的。 当 SameSite=Lax 时,允许某些跨站点请求带上 cookie,比如从其他站点通过 GET 请求链接到当前站点时会携带 cookie。然而,POST 请求、iframe、AJAX 等不会携带 cookie。

一般的转账请求都是使用POST<img/>元素发送的请求是GET,则无法请求成功。

3.使用CSRF token

当用户想转账时,在请求bank.com的转账页面时,bank.com会响应一个CSRF token

Set-Cookie: CSRFtoken=qwerty;

这个CSRF token是一次性的,当用户点击转账时,将CSRF token也一并提交。

bank.com比之前多加了一道验证。不仅验证a用户的token,还要验证用户的CSRF token。验证通过后,转账成功,CSRF token也自动失效。

总结

每种策略都有一定的隐患,因此在实际开发中,通常建议多种防护手段相结合,比如使用 CSRF Token 配合 SameSite Cookie 属性,以达到更强的安全性。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.