CORS 和 CSRF 分别解决什么问题
舒心读
18
卷中目录
遇到“跨域报错”时,容易把 CORS、登录状态和 CSRF 当成同一个问题。实际上,它们位于不同层次。弄清浏览器做了什么、服务器收到了什么,通常比先修改一组响应头更有效。
本篇目标: 区分跨源读取策略与跨站请求伪造防护,避免错误地把一种机制当成另一种保护。

CORS 主要影响脚本能否读取
CORS 是浏览器实施的跨源资源共享机制。服务器通过响应头表达允许哪些源以及相关条件,浏览器据此决定是否把响应交给脚本。某些请求会先进行预检,另一些请求则可能直接发出。MDN:CORS
因此,脚本无法读取响应,不代表服务器没有收到请求。也不能指望 CORS 阻止独立 HTTP 客户端调用接口;业务身份与权限仍需要服务器自己检查。
CSRF 关注带身份的非预期操作
如果浏览器会自动附带身份凭据,攻击页面可能尝试诱导它发出用户没有主动确认的操作。防护需要结合认证方式和请求路径设计,例如校验专用令牌、核对来源信息,以及合理设置 Cookie 属性。
这些措施需要在服务器端执行,不能只靠前端页面隐藏按钮。只读动作和写动作也应保持清楚语义,避免一个看似浏览链接的请求产生重要修改。
排错时分开检查
先观察请求是否到达服务器,是否发生 OPTIONS 预检,再看身份凭据是否按预期发送,最后检查服务端具体拒绝原因。不要为了消除控制台错误,直接允许任意源携带凭据访问。
请求是否发出?
服务器如何认证和授权?
服务器如何验证操作来源?
浏览器是否允许脚本读取响应?
这四个问题可以分别成立,不能用一个 200 状态码或者一条跨域报错代替全部判断。
做一个可重复的小实验
在两个不同源的测试页面间发出只读和写入请求,分别观察网络面板、服务端记录与脚本可见结果。使用完全虚构的测试账号和数据,记录每种凭据策略下的行为。
当观察顺序足够清楚,就能判断该调整共享策略、修正认证配置,还是补上请求伪造防护,而不是在响应头中不断添加字段碰运气。
见字如晤