← 返回题目列表

CORS 配置有哪些安全注意点?

高频 中等 第 9 / 26 题 更新于 2026/07/28
前端安全CORS跨域接口安全

简化版

CORS 是服务端授权浏览器跨源读取响应的机制。安全上不能随意允许所有来源,尤其携带 Cookie 时不能使用 *。应使用明确白名单、限制方法和请求头、正确处理预检请求,并且不要把 CORS 当作接口鉴权。

详细版

常见风险配置:

  • Access-Control-Allow-Origin: * 过于宽泛。
  • 携带凭证时动态反射任意 Origin。
  • 允许过多方法和请求头。
  • 预检请求不校验业务来源。
  • 认为没有 CORS 就能保护接口。

正确做法:

  • 使用可信 Origin 白名单。
  • 携带 Cookie 时明确返回具体 Origin。
  • 配置 Access-Control-Allow-Credentials 要谨慎。
  • 限制允许的方法和请求头。
  • 接口必须做服务端鉴权。

CORS 解决的是浏览器能否把响应交给 JS,不是服务端权限控制。

完整版教学

一、CORS 的安全边界

CORS 是浏览器安全模型的一部分。它决定跨源页面是否能读取响应内容。

但请求本身可能已经到达服务器。因此接口不能依赖 CORS 来判断请求是否可信。攻击者可以用服务器脚本、curl、Postman 直接请求接口。

二、为什么不能随便反射 Origin

有些后端会把请求头里的 Origin 原样返回:

Access-Control-Allow-Origin: <请求里的 Origin>

如果不校验白名单,就等于允许任何网站读取响应。对于携带凭证的接口,这非常危险。

三、携带凭证的特殊规则

跨域请求如果要带 Cookie,需要前端设置 credentials,服务端返回:

Access-Control-Allow-Credentials: true

这时 Access-Control-Allow-Origin 不能是 *,必须是明确来源。否则浏览器会拒绝。

四、面试追问与工程落地

面试官可能问:“CORS 报错是不是前端改一下就能解决?”

多数情况下不是。CORS 授权在服务端响应头中,前端只能按规则发请求。开发环境代理可以绕过浏览器跨域,但生产环境必须由服务端或网关正确配置。

工程中 API 网关应集中管理 CORS 白名单,避免每个服务随意配置。

五、白名单、凭证和缓存要一起设计

动态 CORS 最容易漏掉缓存维度。若服务端根据请求 Origin 返回不同的 Access-Control-Allow-Origin,共享缓存必须知道响应随 Origin 变化:

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Vary: Origin
配置浏览器读取结果风险判断
Allow-Origin: *,无凭证任意来源可读只适合公开数据
精确 Origin + 凭证白名单来源可读登录态接口常用
反射任意 Origin + 凭证任意网站可读用户数据高危错误
多个 Origin 写在一个头里通常无效应按白名单返回单个来源

白名单应把 URL 解析后精确比较 scheme、host、port,不能用 endsWith('example.com'),否则 evil-example.com 也可能通过。还要明确是否接受 Origin: null;沙箱 iframe、本地文件等可能产生 null 来源,默认不应信任。

CORS 的核心问题是“浏览器是否把响应交给调用页面”,不是“请求有没有身份、能不能执行操作”。

六、用数字和攻击路径验证配置

假设接口响应 20KB,前端每分钟调用 30 次,若每次 JSON 请求都先预检,就会多 30 个 OPTIONS。设置合适的 Access-Control-Max-Age 能减少往返,但浏览器会有自己的上限,策略变更也要考虑旧预检缓存窗口。

安全测试要覆盖三类客户端:允许来源的浏览器请求应成功;恶意来源的浏览器 JS 应拿不到响应;curl 即使不带 Origin 仍可能请求成功,但必须因缺少身份或权限而被业务拒绝。第三项正好证明 CORS 不是鉴权。

浏览器页面 → CORS 检查 → 决定 JS 能否读取
非浏览器客户端 ─────────→ 服务端鉴权与授权

简单跨源请求可能不预检并直接到达服务端,所以不能把“预检失败”当作 CSRF 防护。状态修改接口仍需 SameSite、CSRF Token、Origin/Fetch Metadata 校验等独立措施。

七、常见误区与追问

  • 误区:没有 CORS 头,攻击者就无法请求接口。 非浏览器客户端不受 CORS 限制,部分浏览器请求也会先到达服务端。
  • 误区:携带 Cookie 时可以返回 Access-Control-Allow-Origin: * 凭证模式要求明确来源,星号响应不会向前端暴露。
  • 误区:把请求 Origin 原样返回就是通用方案。 未经白名单验证的反射会把任意恶意站点变成受信来源。
  • 追问:动态 Origin 为什么要加 Vary: Origin 防止共享缓存把给 A 来源的响应头错误复用给 B 来源。
  • 追问:为什么 Postman 正常而浏览器报错? Postman 不执行浏览器 CORS 模型,服务端响应可能正常但缺少跨源授权头。
  • 追问:允许 CORS 是否等于允许 CSRF? 两者不同;CORS管读取,CSRF关注借用户凭证执行状态变更。
  • 追问:白名单能否只匹配域名后缀? 不应,应解析并精确比较协议、主机和端口,避免后缀绕过。

八、加强记忆

  1. 作用域:CORS 是浏览器跨源读取授权,不是服务端身份认证。
  2. 凭证规则:Cookie 场景返回精确 Origin,并设置 Allow-Credentials。
  3. 白名单:解析 origin 三元组精确匹配,不反射任意输入。
  4. 缓存:动态响应补 Vary: Origin,预检缓存时间要可控。
  5. 最小授权:只开放必要方法、请求头和暴露头。
  6. 测试闭环:合法浏览器、恶意浏览器、非浏览器客户端三类都要测。