CSRF 检查请求到底来自哪里
浏览器可能为攻击者触发的请求附带会话 Cookie。CSRF 防御检查请求上下文是否可信,却不能证明用户真的看过或有意批准某个动作。 本图描述文章的服务端夹具,不是浏览器实测。SameSite 只减少 Cookie 发送;可信上下文不证明用户意图,XSS 与认证仍需独立防护。 Cookie 无意识地跟随请求 浏览器判别是否带上 Cookie,依据的是目标域名、路径、Secure、SameSite 及其他浏览器规则,而不是「这次请求是由用户先前的什么意图触发的」。于是,来自攻击者网站的页面,也能驱动受害者的浏览器发出一条改变状态的请求——改密、改资料——并且这条请求会带上已登录的会话 Cookie。服务器看到这样一条请求,会以为它来自合法用户。这正是关键:请求带了凭据,并不能证明这是用户的本意;浏览器只是在执行它的 Cookie 规则,而不是用户的意志。 令牌把动作与来源绑定 对策是让「改变状态的动作」带一个攻击者无法预料的参数。服务端为每个会话生成一个不可预测的反 CSRF 令牌,在它自己的表单里带上,提交时再比对;攻击者的跨站页面既没有这个令牌,校验就会失败。配合严格的方法约束——不要让 GET 去改变状态——让「带令牌」成为改变状态的唯一途径。比对必须严格:缺失或不匹配就拒绝,而且绝不接受攻击者自带的 origin。 SameSite 是浏览器护栏 SameSite=Strict 不在跨站请求中发送该 Cookie;显式设置 Lax 时,使用安全方法的顶层导航仍可携带它。这些限制减少凭据被跨站运送的机会,但本设计仍要求服务端校验令牌。同站范围大于同源,浏览器支持和请求上下文也会影响结果。示例采用服务端保存的同步令牌,而非双提交 Cookie;两种模式不能仅因为都叫令牌,就混为同一种实现。源内脚本注入可以替用户发出合法上下文中的请求,所以还需单独防御 XSS。 把 Origin 当作来源信号 请求存在 Origin 时先检查它;缺失时,服务端可以检查 Referer 的来源部分。两个字段都可能缺失,Origin 也可能是字面值 null,不能把这些情况当作同源证据。本夹具有意同时要求有效令牌和可信来源信号,缺一即拒绝;实际兼容策略也应明确写出,不能默默跳过整个保护。应比较完整的协议、主机与端口,不能只匹配域名前缀,防止相似域名通过。 ...