Nginx网关层防CSRF核心是用valid_referers校验Referer(适配表单/后台)和map+Origin校验(适配API),必须包含none、blocked,推荐server_names与严格正则匹配,并配合后端CSRF Token等二次验证。

在网关层用 Nginx 防 CSRF,核心是把非法跨站请求挡在业务服务之前。Referer 和 Origin 校验是最快落地的两种方式,但它们适用场景不同、行为逻辑不同、配置细节也容易出错。下面直接讲清楚怎么配、为什么这么配、哪些坑必须避开。
Referer 校验:适合表单提交、管理后台等传统页面场景
Referer 是浏览器自动携带的来源页地址,Nginx 通过 valid_referers 指令定义合法来源,并用内置变量 $invalid_referer 判断是否放行。
- 基础配置要包含
none和blocked:用户直接输入 URL、从书签打开、或经某些 CDN/代理转发时,Referer 可能为空或被截断,不加这两项会导致大量误拦 - 域名匹配推荐用
server_names+ 显式通配:比如你的server_name是admin.example.com,就写valid_referers none blocked server_names *.example.com;,比硬写正则更稳 - 避免用简单字符串匹配(如
"example.com"):它会匹配任意含该子串的 Referer,比如evil-example.com也能过;必须用正则并严格锚定,例如~*^https?://([a-z0-9.-]+\.)?example\.com(/|$) - 校验动作统一放在
location块开头:if ($invalid_referer) { return 403; },不要混在 proxy_pass 后面
Origin 校验:更适合 API 接口、前后端分离架构
Origin 头由浏览器在跨域请求中强制添加,且不可被前端 JavaScript 修改,比 Referer 更可信。但它只出现在 CORS 请求中(如 fetch、XMLHttpRequest),普通表单提交不会带。
- 优先用
map模块做白名单映射:比反复if判断更高效、更安全(Nginx 官方不建议在 location 中频繁使用 if) - 示例配置:
map $http_origin $allow_origin { default ""; "~*^https?://(www\.)?example\.com$" "$http_origin"; "~*^https?://api\.example\.com$" "$http_origin"; }然后在 location 中:if ($allow_origin = "") { return 403; } - 注意 Origin 值可能为
null(如 iframe sandbox 场景)或空字符串,需在 map 中显式覆盖""和"null"的情况 - Origin 校验不能替代 Referer 校验:两者覆盖的请求类型不同,关键接口可同时启用,但需注意响应头冲突(如 Access-Control-Allow-Origin 不应与校验逻辑矛盾)
绕过 Referer/Origin 的常见情况,必须提前应对
光配对了规则还不够,真实流量里总有“例外”。以下几类请求不走常规 Referer/Origin 路径,若没兼容,会直接拒掉正常用户:
- 移动端 WebView 内嵌页:部分安卓 WebKit 内核在跳转时可能清空或不发 Referer,建议对移动端接口放宽
none blocked,或结合 User-Agent 做二级识别 - HTTPS → HTTP 跳转:浏览器出于安全策略会丢弃 Referer,如果站点同时支持 http/https,需在 valid_referers 中同时允许两种协议
- CORS 预检请求(OPTIONS):它本身不带 Origin?错——它带,但值是实际请求的 Origin。确保 OPTIONS 请求也被同一套 Origin 规则覆盖,否则预检失败,后续请求根本发不出
- 本地开发环境(localhost):前端调试常走
http://localhost:3000,务必把开发域名加入白名单,否则连自己都调不通
不能只靠 Nginx:必须配合后端二次验证
Nginx 层校验只是第一道过滤网,不是最终防线。原因很实在:
- Referer 和 Origin 都可被攻击者在非浏览器环境(如 curl、Postman、脚本)中任意伪造
- 某些企业防火墙、隐私插件、浏览器设置会主动剥离 Referer,导致合法用户被误杀
- Nginx 无法验证用户身份上下文(比如 session 是否有效、token 是否过期)
- 所以,Nginx 做的是“快速筛掉明显非法请求”,减轻后端压力;后端仍需校验同步令牌(CSRF Token)、SameSite Cookie、或签名参数等深度防护手段











