csrf过滤器未生效的根本原因是配置开关与执行拦截两步未走全:需在security.php设$csrfprotection为'cookie',并在filters.php的$globals['before']中显式注册'csrf'过滤器;ajax请求失败因$csrfregenerate=true导致令牌过期,须响应头返回新x-csrf-token并前端动态更新;esc()函数必须按上下文正确使用,否则仍存xss风险。

CSRF过滤器没生效,表单提交直接403或跳过验证
根本原因不是框架坏了,而是“配置开关”和“执行拦截”两步没走全。CI4的$csrfProtection在app/Config/Security.php里设成'cookie'只是准备令牌,真正拦请求的是csrf过滤器——它必须显式注册。
- 检查
app/Config/Filters.php中$globals['before']是否包含'csrf',例如:'before' => ['csrf'] - 若只对POST接口防护,改用
$methods['post'] = ['csrf'],避免GET路由被误拦 - 别在CI4里写
$config['csrf_protection'] = TRUE——这是CI3语法,CI4完全忽略 - 启用后测试:手动删掉表单里的
= csrf_field() ?>再提交,应立刻返回403;否则过滤器根本没跑
AJAX请求总在第二次失败,报403
因为CI4默认$csrfRegenerate = true,每次请求都换令牌,但前端JS通常只在页面加载时读一次csrf_hash(),后续请求还在用旧值。
- 后端响应必须带新令牌:
return $this->response->setHeader('X-CSRF-TOKEN', csrf_hash()); - 前端不能用
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': staticToken } })硬编码——得每次从响应头动态取:xhr.getResponseHeader('X-CSRF-TOKEN') - 如果用Fetch,记得在
then()里更新全局token变量,而不是初始化时赋值一次 - Cookie模式下,确保前端读取的cookie名和
$csrfCookieName一致,默认是ci_csrf_token
esc()函数用错上下文,XSS依然能打穿
esc()不是万能胶布,它只按指定上下文转义。把HTML内容用'js'类型输出,等于给攻击者递刀。
- 输出到HTML正文(如评论内容):用
= esc($data, 'html') ?> - 拼进JavaScript字符串(如
var msg = "= esc($msg, 'js') ?>";):必须用'js' - 塞进URL参数(如
<a href="https://www.php.cn/link/0a4a525a2fbaa419814c9e8c3a119b7a'url')%20?>">):选<code>'url',否则&可能被解析为参数分隔符 - 写进CSS样式(如
style="color: = esc($color, 'css') ?>"):用'css',防expression()等危险语法 - 富文本内容(如编辑器输出)不能只靠
esc(),得用HTML Purifier白名单过滤,否则<img onerror="alert(1)">照样执行
CSRF保护开了,但敏感操作还是被绕过
CSRF只管“是不是用户自己发的请求”,不管“这个请求合不合理”。它不校验ID归属、不拦参数篡改、不防越权访问——这些得靠其他机制补位。
- 删除用户时,仅验证CSRF令牌不够,还得在控制器里查
$this->request->getPost('id')是否属于当前登录用户 - 上传文件名含
../../.htaccess?CSRF不管这事,得用$this->validation->setRules()加正则白名单,比如['upload_name' => 'regex_match[/^[a-zA-Z0-9._-]+$/]'] - 数据库更新用
Model::update()前,确认$allowedFields已声明,否则admin=1这种字段可能被恶意POST进来 - 别依赖
$globalXSSFiltering = true——它会全局strip_tags,把合法的©也干掉,且对JSON POST无效
真正容易漏掉的,是CSRF令牌和会话存储方式的隐性耦合:比如你设了$csrfProtection = 'session',但session驱动用的是file,而服务器磁盘满导致session写失败——此时令牌生成失败,所有POST都会403,但错误日志里可能只报“session write failed”,不提CSRF。











