valid_referers 无法完全防御伪造 referer,仅做字符串匹配,不验证真实性;其有效场景限于浏览器自然跳转且未清空 referer 的请求,需配合 secure_link、token 验证等多层防护。

不能完全过滤掉所有伪造 Referer 头的恶意脚本。valid_referers 本身不验证请求真实性,只做字符串匹配,而 Referer 字段可被 curl、Postman、自动化脚本任意构造,Nginx 无法识别真假。
valid_referers 的实际作用边界
它只对浏览器自然发起、且未被清除 Referer 的页面请求有效。例如用户从 https://a.com/page.html 点击链接跳转到你的图片地址,浏览器会带上 Referer;但攻击者用脚本发请求时,可随意设 Referer: https://evil.com 或 Referer: ,Nginx 照样接收并按规则比对——只要该值落在白名单里(比如你写了 ~\.evil\.com$ 或误配了通配符),就放行。
- 它不是安全认证机制,本质是“来源提示校验”,不是“身份鉴权”
- HTTPS 页面加载 HTTP 资源时,浏览器会清空 Referer,导致合法访问也被拦截
- APP、小程序、CLI 工具、CORS 请求通常不带 Referer,启用后直接 403
真正能缓解伪造 Referer 的配置要点
不是靠“堵死所有伪造”,而是缩小攻击面、提高脚本成本、配合其他层防御:
- 白名单尽量收紧:只写确切域名,避免
*.example.com这类宽泛通配;不用正则除非必要,防止~\.com$匹配到所有 .com 域名 - 必须保留
none:允许直接访问(如用户输入图片 URL)、书签访问、部分隐私模式场景,否则大量真实流量会失败 - 搭配
blocked:接受 Referer 存在但协议/路径缺失的情况(如代理转发后只剩example.com),减少误拦 - 把 if 判断严格放在静态资源 location 内,且置于
proxy_pass或try_files之前,避免规则失效
必须叠加的补充手段
单靠 Referer 校验无法防住有意伪造,需组合使用:
-
secure_link 模块:生成带时效和哈希签名的 URL(如
/img/logo.png?md5=abc123&expires=1721562000),Nginx 自动校验,伪造参数立即失效 -
一次性 Token + Cookie 验证:前端跳转前由后端下发短时效 token,Nginx 读取
$cookie_token并调用 auth_request 模块校验,绕过 Referer 依赖 - IP 行为限频:对同一 IP 在单位时间内请求图片超阈值的,用 limit_req 直接拒绝,不管 Referer 是什么
-
日志监控 + 动态封禁:记录
$http_referer和$invalid_referer,发现高频非法 Referer 自动加入 deny 列表
调试与验证建议
上线前务必验证是否误伤正常流量:
- 用 curl 手动测试:
curl -e "https://yourdomain.com" https://yoursite.com/logo.png(应成功) - 测试空 Referer:
curl -H "Referer:" https://yoursite.com/logo.png(有none才应成功) - 检查 Nginx 日志是否开启 Referer 记录:
log_format main '$http_referer $invalid_referer $status ...'; - 避免在 API、登录、支付等关键路径使用 valid_referers,这些接口本就不该依赖 Referer











