Skip to content

CSRF 是什么,怎么防? ​

CSRF 是诱导已经登录的浏览器,向目标站点发出用户并未打算发出的请求。浏览器会自动带上该站点的 Cookie,所以服务器以为是用户本人。防御用 SameSite Cookie、CSRF 令牌,以及校验 Origin。

原理 ​

攻击页面无法读取另一个源的响应,但可以发起请求:自动提交的表单、隐藏的图片地址。只要目标接口只靠 Cookie 认人,这个请求就会带登录态。

三层做法:

  1. SameSite Cookie。Lax 在跨站时不带 Cookie,但顶级导航的 GET 仍会带;Strict 更严;None 必须同时 Secure。新浏览器对未声明的 Cookie 往往按 Lax 处理,不能只靠默认值,要显式设置。
  2. CSRF 令牌。服务器把一段随机值放进页面或响应里,真正改数据的请求把它放在自定义头或表单字段里带回来。跨站表单加不了自定义头,读不到另一个源的令牌,所以伪造请求对不上。
  3. 校验 Origin 或 Referer。改状态的请求,来源应该是自己的站点。有些隐私设置会拿掉 Referer,所以它是辅助。

改数据的接口不要用 GET。GET 可以被图片和链接触发。

追问 ​

有了 XSS,CSRF 令牌还有用吗?

注入脚本跑在本源里,能读页面上的令牌,也能发带令牌的请求。CSRF 防的是「别的网站」。本源里的脚本要靠防 XSS 解决。

CORS 能防 CSRF 吗?

简单的跨站表单不需要通过 CORS 检查就能发出。CORS 决定的是脚本能不能读到响应,不是请求发不发得出去。见 跨域。

易错点 ​

  • 把 CSRF 说成「攻击者读到了用户的数据」。读响应是同源策略的事;CSRF 是借浏览器把请求发出去。
  • 只在前端藏按钮没有用,接口自己要校验。
  • SameSite=Lax 仍然允许顶层 GET 导航带 Cookie,所以 GET 不能改数据。

相关 ​