CSRF 的中文名是跨站请求伪造:攻击者借用户浏览器里已登录的会话,让用户在不知情时发出自己不想发的请求。理解它为什么能成立,Token 的每个设计细节就都有了出处。
## 攻击为什么能成立
浏览器对目标站点的请求会自动携带该站点的会话凭据。用户在某站点保持登录时,访问了攻击者控制的页面,该页面里藏着一个向目标站点发起操作请求的元素,浏览器发出请求时自动带上了登录凭据,服务端看到合法会话就执行了操作。整个过程中攻击者拿不到凭据内容,也不需要拿到,浏览器替他把凭据送上了门。这就是 CSRF 的本质:劫持的是浏览器的自动携带行为,而非凭据本身。
## Token 的防御逻辑
防御思路是让请求携带会话之外的第二重凭据,而这重凭据攻击者页面拿不到。服务端在生成表单时嵌入随机 Token,提交时校验 Token 是否匹配。攻击者页面构造的请求可以带上会话凭据,但无法读到目标站点的 Token 内容,同源策略挡住了跨站读取,校验失败请求被拒。这个逻辑有两个推论:Token 要足够随机不可预测;Token 的读取通道必须与注入通道隔离。
## 正确姿势的要点
第一,Token 校验失败要拒绝请求,而不是降级放行,形同虚设的校验不如不做。第二,Token 与会话绑定,会话重建时刷新。第三,关键操作再做一层确认:修改密码、绑定手机这类敏感动作要求输入当前密码,即使 Token 被绕过也有兜底。第四,配合会话凭据的同站属性设置,从浏览器侧减少自动携带的场景。第五,不要用凭据本身派生的字段当 Token,攻击者虽读不到内容,但有些攻击形态可以让浏览器原样带上整个凭据。
## 常见错误
GET 请求承载状态变更操作,一个图片链接就能触发;Token 全站共用长期不变,泄露一次全线失守;校验逻辑只在部分接口生效,攻击者专挑没防护的入口;忽略来源检查的辅助价值,多层防御里这层虽然不完美但成本极低。顺云用户的应用在实现 Token 校验时,把上述要点过一遍,CSRF 的攻击面就能基本闭合。