CORS 与它的配置风险
浏览器的同源策略默认禁止跨域读取响应,跨域读取必须由服务端通过 CORS 响应头显式放行。风险出现在放行规则过宽时:如果服务端把请求里的 Origin 原样反射回 Access-Control-Allow-Origin,同时又返回 Access-Control-Allow-Credentials: true,任何站点都能带着用户的登录态读取该接口数据,等同于绕过同源策略。
基本信息
| 危险组合 | 反射任意 Origin 加 Access-Control-Allow-Credentials: true |
|---|---|
| 次危险 | 对敏感接口使用 Access-Control-Allow-Origin: * |
| 检查方法 | 用自建测试源发起跨域请求,观察响应头 |
| 复核要求 | 简单请求与预检请求都要核对 |
| 边界 | 只观察响应头,不抓取真实用户数据 |
典型使用场景
- 前后端分离项目:核对 API 域名与前端域名的放行关系
- 开放平台与嵌入式场景:确认放行是否精确到注册域名
- 子域互信场景:检查是否用前缀匹配代替精确匹配
- SSO 与跨域单点登录:核对凭据模式下的放行范围
- 修复复测:确认收紧后业务功能仍正常
检查步骤
检查步骤
curl -sI -H "Origin: https://test-origin.example" https://target.example/api/profile
# 观察 Access-Control-Allow-Origin 是否为该来源本身
# 观察 Access-Control-Allow-Credentials 是否为 true
# 再发一次预检请求,核对方法与方法头的放行
curl -si -X OPTIONS -H "Origin: https://test-origin.example" \
-H "Access-Control-Request-Method: PUT" https://target.example/api/profile响应头读法
| 响应头 | 含义 | 风险判断 |
|---|---|---|
| Access-Control-Allow-Origin | 允许的来源,可为具体值、星号或 null | 反射任意来源即高风险 |
| Access-Control-Allow-Credentials | 是否允许携带凭据 | 为 true 且来源可反射时风险最高 |
| Access-Control-Allow-Methods | 预检允许的方法 | 放行写方法需确认是否必要 |
| Vary: Origin | 缓存是否按来源区分 | 缺失可能导致缓存串源 |
修复视角:用精确白名单匹配(含协议与端口),避免用字符串包含或后缀匹配判断来源;敏感接口避免允许携带凭据的跨域访问。
仅返回星号的公开接口本身不是漏洞,关键在于接口返回的数据是否敏感、是否依赖登录态。
复核与整改要点
- 同一接口在未登录与已登录状态下分别发送跨域请求,比对响应头是否变化
- 核对携带凭据的请求是否被放行,重点看凭据模式下的实际返回
- 确认放行规则是精确域名匹配,而不是前缀、后缀或包含判断
- 整改后回归业务功能,确认前端跨域调用仍然正常
- 记录测试来源、请求方法与响应头取值,作为复核依据