防止敏感数据因cors配置不当泄露,核心是拒绝反射origin和禁用通配符*,改用可验证的动态白名单;nginx需通过map指令实现安全映射,并在location中校验$ cors_origin非空才添加响应头,否则返回403拦截。

防止敏感数据因 CORS 配置不当泄露,核心是拒绝“反射 Origin”和禁用通配符 *,改用可验证、有边界的动态白名单。Nginx 不校验请求真实性,只负责声明;声明错了,浏览器就静默拦截——但更危险的是声明太宽,让恶意站点合法拿到响应。
严格限制 Access-Control-Allow-Origin 值
带凭证(如 Cookie、Authorization)的请求,Access-Control-Allow-Origin 绝不能为 *。否则浏览器直接拒绝响应体,前端报错却看不到真实数据——但若配置成 Origin 反射(即原样回传请求头里的 Origin),攻击者就能伪造任意源发起请求,窃取用户会话或敏感接口返回。
- 只允许明确可信的前端域名,例如
https://app.example.com、https://admin.example.net - 同一主域下的子域(如
api.example.com和www.example.com)可考虑用$http_origin配合白名单,而非硬编码 - 禁止使用
https://*.example.com这类无效通配语法;Nginx 不支持域名通配符匹配,必须靠正则或 map 实现
用 map 指令实现安全的动态白名单
在 http 块顶部定义映射,将合法 Origin 映射为非空值,非法来源映射为空字符串。后续通过变量控制响应头是否添加,比 if + set 更高效、更可靠。
- 示例配置:
map $http_origin $cors_origin { default ""; "~^https?://(app|admin|staging)\.example\.com$" "$http_origin"; "~^https?://localhost:3000$" "$http_origin"; } - 在
location中仅当$cors_origin非空时才加头:add_header 'Access-Control-Allow-Origin' $cors_origin always; add_header 'Access-Control-Allow-Credentials' 'true' always;
- 若
$cors_origin为空,Nginx 不添加该头,浏览器按默认策略拒绝跨域,无响应暴露风险
拦截非法 Origin 并主动拒绝请求
仅不加响应头还不够——有些客户端可能忽略 CORS,或通过非浏览器环境直连。应在 Nginx 层级直接拦截非法来源,返回 403。
- 在 location 内添加判断:
if ($cors_origin = "") { return 403; } - 配合日志记录非法 Origin,便于审计:
log_format cors_log '$remote_addr - $http_origin "$request" $status'; - 避免仅依赖后端校验:Nginx 是第一道网关,前置拦截能降低后端负载并阻断恶意调用链
同步加固 Referer 泄露与其它响应头
CORS 安全不是孤立的。Origin 控制谁来调用,Referer 控制你跳去哪时泄露什么。两者配合才能防住完整攻击路径。
- 配置
Referrer-Policy: strict-origin-when-cross-origin,确保跨域跳转时不发送含敏感参数的完整 URL - 强制添加基础安全头:
X-Content-Type-Options: nosniff、X-Frame-Options: SAMEORIGIN、Strict-Transport-Security - 禁用
Access-Control-Allow-Headers: *,显式列出必需头(如Content-Type、Authorization),避免暴露内部鉴权机制











