cors

所谓cors其实就是浏览器的跨站请求协议
cors和csrf的区别就是一个是利用img等标签来操控用户行为看不到其返回的值,一个是通过跨站请求来获取敏感信息。

主要原因是在某些网站是需要允许跨站资源访问的,这时候就一套允许携带cookie的跨站协议。
而cors由几个请求头来进行操控
Access-Control-Allow-Origin:
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers:

Origin就是其允许的域如果这个返回值可控或者这个返回值为*即可跨域来获取用户的某些信息
主要是fetch这里ajAX请求

下面这个文章写挺好的
https://forum.butian.net/share/2901

危险组合一:最严重 — 任意 Origin 回显 + 允许带凭证

请求(由攻击者发送):

1
Origin: https://attacker.com

服务器响应(危险):

1
2
3
4
Access-Control-Allow-Origin: https://attacker.com    // 或直接回显请求的 Origin
Access-Control-Allow-Credentials: true
Set-Cookie: session=...; HttpOnly; Secure
Vary: Origin (缺失则更危险)

危险性:攻击者页面可以 fetch(..., { credentials: 'include' }),浏览器既会把目标站点 cookie 发出,又会把响应 body 交给攻击者脚本,完全泄露登录用户的私有数据
检测(curl 看头):

1
curl -i -H "Origin: https://attacker.com" https://target.example/api/secret

浏览器验证(真实可利用):

1
2
fetch('https://target.example/api/secret', { credentials: 'include' })
.then(r => r.text()).then(t => console.log(t))

修复:不要回显任意 Origin;如果必须允许凭证,只返回白名单中的具体域名,并添加 Vary: Origin


危险组合二:Allow-Origin: * 与敏感响应 / 误配凭证

请求:

1
Origin: https://attacker.com

响应(松散/错误):

1
2
3
4
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: *
Access-Control-Allow-Credentials: true // 有些错误实现会返回这个(或老旧/代理问题)

危险性:按规范 * 不应与 Allow-Credentials: true 同时使用;现代浏览器会忽略 *+credentials 组合,但错误的代理/旧浏览器/自制客户端或缓存不当可能造成泄露。即便没有凭证,公开敏感接口也可能被任意站点读取。
检测(curl):

1
curl -i -H "Origin: https://attacker.com" https://target.example/api/secret

修复:不要用 * 对敏感数据开放;若需要公开 API,确保其仅返回公共数据且不依赖 cookie;敏感接口需白名单 + credentials 控制。


危险组合三:回显 Origin + 允许宽松 Methods/Headers(扩大发现面)

请求(触发预检):

1
2
3
Origin: https://attacker.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Requested-With, Authorization, Content-Type

响应(危险):

1
2
3
4
5
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true // 或存在
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH // 过宽
Access-Control-Allow-Headers: Authorization, X-Requested-With, Content-Type, *
Access-Control-Max-Age: 86400

危险性:若服务允许任意方法和任意头并允许凭证,攻击者可使用复杂请求(带 Authorization 或自定义头)并长期复用(Max-Age)。
检测(curl 预检):

1
2
3
4
5
curl -i -X OPTIONS \
-H "Origin: https://attacker.com" \
-H "Access-Control-Request-Method: POST" \
-H "Access-Control-Request-Headers: Authorization" \
https://target.example/api/secret

修复:限制允许的方法与头到业务最小集合;不要用 *;缩短 Max-Age


危险组合四:Expose-Headers 过度暴露敏感头

响应(危险):

1
2
3
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: Set-Cookie, Authorization, X-User-Email

危险性:Expose-Headers 允许跨域脚本读取原本受保护的响应头。如果这些头包含敏感信息(如 Authorization token 或自定义 session info),会被窃取。
检测(fetch):

1
2
fetch('https://target.example/api/secret', { credentials: 'include' })
.then(r => { console.log(r.headers.get('Authorization')) })

修复:不要把敏感 header 列在 Access-Control-Expose-Headers 中;仅暴露必要的非敏感头。


危险组合五:缺少 Vary: Origin 导致 CDN/缓存中毒

请求:

1
Origin: https://attacker.com

响应(危险):

1
2
3
Access-Control-Allow-Origin: https://attacker.com   // 动态回显
Access-Control-Allow-Credentials: true
// **没有** Vary: Origin

危险性:代理或 CDN 可能缓存带有回显 Allow-Origin 的响应并对其他用户返回同一缓存,造成跨用户的数据泄露或扩大攻击面
检测(通过代理/CDN 配置与缓存行为测试)
修复:当动态返回 Access-Control-Allow-Origin,务必加 Vary: Origin;并确保 CDN 不缓存敏感动态响应(Cache-Control: private/no-store)。


危险组合六:*对预检允许任意 header(Access-Control-Allow-Headers: )**

请求(预检):

1
2
3
Origin: https://attacker.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, X-Custom-Auth

响应:

1
2
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Headers: * // 或列出 Authorization 等敏感头

危险性:攻击者可以发送带任意敏感自定义头(例如伪造 Authorization)或触发更有力的请求。
修复:明确列出被允许的 header,避免 *,并在服务端对 header 值作严格校验。


危险组合七:允许 OPTIONS / 预检 但不限制来源

响应:

1
2
3
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Methods: *
Access-Control-Allow-Headers: *

危险性:预检放行所有方法与头会使攻击者能以任意复杂度发起跨域请求并读取响应(若同时允许凭证)。
修复:只允许实际使用的方法和头;对预检请求进行源白名单校验。


危险组合八:Set-Cookie 与回显 Origin / Allow-Credentials

请求:

1
Origin: https://attacker.com

响应(危险):

1
2
3
Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true
Set-Cookie: session=...; HttpOnly; Secure; SameSite=None

危险性:服务器在跨域响应中下发 cookie(且允许凭证),这可能使攻击者诱使浏览器在后续请求中发送该 cookie(会话劫持或持久化)。
修复:避免在跨站响应中设置敏感 cookie;如果必须,确保只在可信来源下设置并做严格验证。


危险组合九:Access-Control-Allow-Origin 回显任意 Origin,但没有 Allow-Credentials(仍可能泄露公共数据)

响应:

1
2
Access-Control-Allow-Origin: https://attacker.com   // 回显任意 Origin
Access-Control-Allow-Credentials: false (或无)

危险性:虽然不能带凭证,但若接口返回敏感数据(误将私人数据当公共数据返回),攻击者仍然能读取。
修复:区分公共 API 与敏感 API;敏感 API 不应回显任意 Origin。


辅助:攻击者常用的“请求头组合”用于探测与预检

  • 基本探测:
1
Origin: https://attacker.com
  • 触发预检(测试复杂跨域权限):
1
2
3
Origin: https://attacker.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Authorization, X-Requested-With
  • 测试是否会接受凭证/cookie:

    • 在攻击者页面使用 fetch(..., { credentials: 'include' }) 发真实请求(浏览器行为决定是否发送 cookie);同时用 curl 带 Origin 看响应头。
  • 测试是否能读取特定 header:

    • 请求后看 Access-Control-Expose-Headers 包含什么。

快速检测脚本(curl + fetch POC)

  1. 用 curl 看响应头(初筛):
1
curl -i -H "Origin: https://attacker.com" https://target.example/api/secret
  1. 若返回 Access-Control-Allow-Origin 并且可能有 Allow-Credentials: true,在 attacker.com 的浏览器控制台试:
1
2
fetch('https://target.example/api/secret', { credentials: 'include' })
.then(r => r.text()).then(t => console.log(t)).catch(e => console.error(e));

若能拿到 body,就是真实可利用漏洞。


总结与防护要点(一眼清单)

  • 危险组合的核心:回显任意 Origin (ACAO 回显) + Access-Control-Allow-Credentials: true + 可读的响应体/头。这是最危险的一类。
  • 其他危险:ACAO: * 对私有数据开放、Allow-Headers: * / Allow-Methods: * / 过度 Expose-Headers、缺 Vary: Origin 等都能放大问题或绕过保护。
  • 修复总策略:白名单 Origin + 不对敏感接口使用 * + 当允许凭证时只返回具体可信域 + 加 Vary: Origin + 限制 Methods/Headers/Expose-Headers 并在服务端做严格授权验证

如果你想,我可以接着做两件事(任选其一):

  1. 把上面所有危险组合整理成一张便于复测的清单(CSV 或表格),包含检测 curl 命令与风险等级;
  2. 帮你审查某个站点的真实响应头 —— 你把 curl -i -H "Origin: https://attacker.com" https://target/... 的输出贴上来,我直接指出哪些头造成漏洞并给出精确修复代码/配置(比如 Nginx、Express、Spring Boot 的示例)。

你想先要哪一个?