referer校验不是csrf防护主力而是辅助手段,thinkphp依赖token机制(__token__字段+session比对),referer仅作可选补充;其局限性强,易被绕过或误杀,真正关键在于token生成、提交与session一致性验证。

Referer校验不是CSRF防护主力,而是辅助手段
ThinkPHP本身不依赖Referer防CSRF,app_csrf_state开启后走的是Token机制——__token__字段 + session比对。Referer检查只是可选的补充动作,不能替代Token验证。强行把它当“必须”项,反而会掩盖真实漏洞:比如Token根本没启用、validateToken()漏调、session驱动异常等。
Referer能解决什么,又容易出什么问题
Referer头在特定场景下有用,但局限性极强:
- 它只对浏览器发起的表单提交或a标签跳转有效;curl、Postman、APP、小程序等根本不发Referer,一拦就挂
- 用户禁用Referer(如隐私插件)、HTTPS→HTTP跳转会清空Referer,导致合法请求被拒
- 攻击者可用
meta referrer或伪造Header绕过,不能当作安全边界 - 多级代理、CDN、前端重定向可能修改或丢弃Referer,线上环境极易误杀
真正该盯住的是:__token__是否生成、是否提交、是否被提前读取、session是否一致。
什么时候才值得加Referer检查
仅在明确知道请求来源可控、且需快速过滤明显异常流量时,作为日志标记或灰度分流依据:
- 后台管理页限制只允许来自
/admin/路径的Referer,用$this->request->header('referer')简单匹配 - 微信小程序跳转页,检测
miniProgram关键词做UA+Referer双判(注意:Referer值可能是https://servicewechat.com/...) - 配合日志埋点,发现大量Referer为空或来自恶意域名的POST请求,用于触发告警而非拦截
别写if (!strpos($referer, 'yourdomain.com')) die('no access');这种硬拦截——它既不安全,也不健壮。
Token失效时Referer拦不住任何攻击
如果Token机制本身崩了,Referer就是个摆设:
-
app_csrf_state为false,中间件压根不跑,所有POST畅通无阻 - 模板写了
{:token()},但控制器没调validateToken(),或只在index里加了,save方法漏掉 - 用了
input('post.')提前消耗输入流,validateToken()拿不到__token__字段,直接返回false - Redis session驱动配置错误,每次请求都新建session,导致token存进去、下次取不到
遇到“非法请求”,第一反应不该是查Referer,而是dump(input('__token__'))和dump($this->app->session->get('__token__'))——两个值对不上,就说明Token链路断了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











