配置Nginx和Tomcat的CORS头后仍被检测到Access-Control-Allow-Origin为null怎么办
问题原因
- 扫描工具和浏览器的请求逻辑不同:WebInspect扫描时会主动构造
Origin: null的恶意请求,测试CORS配置的边界;而你浏览器测试时是从合法的*.example.com域名发起请求,Origin头为业务域名,自然返回的是你配置的允许值。 - 双配置冲突:你同时在Tomcat的web.xml和Nginx中配置了CORS响应头,当请求的Origin为
null时,Tomcat的CORS配置可能匹配到了null值,返回了Access-Control-Allow-Origin: null,而你Nginx的配置只覆盖了/frontend路径,其他路径的请求还是由Tomcat返回响应头,导致扫描到null值。 - Nginx配置存在缺陷:你当前使用的
add_header指令默认仅在200、201、204、206、301、302、303、304、307、308这类响应码下才会追加头,若扫描工具触发了4xx/5xx响应,就不会返回你配置的CORS头,反而拿到Tomcat返回的null值。
验证方法
你可以直接用curl构造恶意请求确认是否为误报:
curl -H "Origin: null" -v https://你的目标域名/任意路径
如果返回的响应头中存在Access-Control-Allow-Origin: null,则说明不是误报,确实存在CORS配置漏洞。
修复方案
- 统一CORS配置入口:删掉Tomcat web.xml中的CORS相关配置,仅保留Nginx侧的配置,避免双配置冲突。
- 修改Nginx配置,增加Origin校验和always参数,示例配置如下:
# 全局或者对应location块下配置 if ($http_origin ~* ^https?://.*\.example\.com$) { add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" always; add_header Access-Control-Allow-Credentials true always; } # 拦截非法Origin请求 if ($http_origin !~* ^https?://.*\.example\.com$) { return 403; } # 处理OPTIONS预检请求 if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS, PUT, DELETE" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization" always; add_header Access-Control-Max-Age 86400 always; return 204; }
- 修复完成后,再次用curl模拟
Origin: null、Origin: https://evil.com等非法请求,确认不会返回允许跨域的头,再重新执行扫描即可。
内容的提问来源于stack exchange,提问作者Anchiao C.
相关产品推荐
相关产品推荐

