严重程度:高危配置错误
CORS 配置错误:通配符与回显陷阱
跨源资源共享(CORS)控制哪些其他网站可以读取你 API 的响应。使用通配符或回显 origin 的策略,可能让任何网站都能发起带凭据的请求并读取结果。
这是什么
浏览器默认阻止跨源读取。CORS 响应头会有选择地放宽这一限制。Access-Control-Allow-Origin: * 会把响应向所有网站开放。
一种更隐蔽的错误是 origin 回显:服务器把请求携带的任意 Origin 原样回显到 allow-origin 响应头里,看似有针对性,实际上等于信任了所有人。
为什么重要
如果你的 API 提供用户数据并允许携带凭据,过于宽松的 CORS 策略会让恶意网站直接从你的 API 读取已登录受害者的数据。
回显再加上 Access-Control-Allow-Credentials: true 尤其危险——它会瓦解本应保护用户数据私密性的同源防护。
如何修复
只允许特定的源
根据一份固定的受信任域名列表校验请求的 Origin,只有通过后才把它回显。
const ALLOWED = new Set(["https://app.yourdomain.com"]);
const origin = req.headers.get("origin") ?? "";
const allow = ALLOWED.has(origin) ? origin : "";
// only set the header when allow is non-empty 绝不要把通配符和凭据一起用
浏览器禁止 Access-Control-Allow-Origin: * 与凭据同时使用,于是有些应用改为回显 origin——而这正是漏洞所在。请改用严格的允许列表。
默认不开启 CORS
如果某个 endpoint 不需要跨源访问,就完全不发送 CORS 响应头。只对确实需要的特定路由开放。
常见问题
Access-Control-Allow-Origin: * 总是不好的吗?
对真正公开、不带凭据的资源(例如公开字体或开放数据 API)来说并不是。但对任何与用户会话绑定的东西来说都很危险。
CORS 能保护我的服务器吗?
不能——CORS 由浏览器强制执行,而非服务器。它管的是其他网站的 JavaScript 能读取什么,而不是请求能否到达你。