XSRF浅析

60 阅读3分钟

定义

CSRF(Cross-site request forgery)简称:跨站请求伪造。是一种利用用户已登录的身份,在用户不知情的情况下,诱导用户点击链接或访问恶意网站,发起伪造请求的方式。常见的CSRF攻击场景包括转账、修改密码、发帖等。

原理

这里的跨站请求伪造,主要是利用了cookie的特性,http是无状态的,cookie的出现是为了记录用户的登录状态,但是它不够安全,其中一个原因是cookie最初被设计成了允许在第三方网站发起的请求中携带,CSRF的攻击就是利用了这一“弱点”

比如我们在浏览器中打开 a.com 站点下的一个网页后,该页面发起请求的 URL 不一定也是 a.com 上的,可能有 b.com 的,也可能有 c.com 的。我们把发送给 a.com 上的请求叫做第一方请求(first-party request),发送给 b.com 和 c.com 等的请求叫做第三方请求(third-party request),第三方请求和第一方请求一样,都会带上各自域名下的 cookie,所以就有了第一方 cookie(first-party cookie)和第三方 cookie(third-party cookie)的区别。上面提到的 CSRF 攻击,就是利用了第三方 cookie 。

如何防御

  • 尽量使用post
  • 加入验证码
  • referer请求头校验
  • Anti CSRF Token
  • 加入自定义的header
  • 设置cookie的sameSite属性

因为csrf主要利用了cookie的特性,所以下面着重说明几个cookie的属性

Cookie的sameSite

Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。它可以设置三个值

  • strict

    最为严格,完全禁止第三方cookie,跨站点时,任何情况都不会发送cookie,换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。

    可能带来的问题,比如说,如果你的网站是淘宝,用了 Strict 会这样:某微商在微博上发了条消息"新百伦正品特卖5折起 item.taobao.com/item.htm?id… 结果点进去顾客买不了,也就是说,这种超多用户的、可能经常需要用户从别的网站点过来的网站,就不适合用 Strict 了

  • lax(默认)

    规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

    image.png 设置了StrictLax以后,基本就杜绝了 CSRF 攻击。当然,前提是用户浏览器支持 SameSite 属性。

  • none

    使用None的话,在任何情况下都会发送Cookie数据。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

跨站和跨域

cookie 的samesite校验的是跨站,而不是跨域,那跨站和跨域有什么区别呢

  • 跨域是指域名、协议、端口号三者中有一个不同就是跨域
  • 跨站是指子域名不同,如果子域名相同,但是协议和端口号不同的话不属于跨站,eg:a.jzplp.comb.jzplp.com属于同站

Secure 和httpOnly

基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie打出cookie的内容。

Secure属性是说如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的