thinkphp 6 已彻底移除 default_filter 全局过滤机制,配置无效;防 xss 必须显式使用 input() 第三个参数、模板 |html 过滤器或针对性中间件,禁用全量自动过滤。

ThinkPHP 6 的 filter 配置已失效,别再往 app.php 里写 'default_filter' => 'htmlspecialchars'
ThinkPHP 6 彻底移除了全局默认过滤机制,default_filter 配置项被忽略,任何在 config/app.php 中设置的自动转义都会静默失效。这不是配置没生效,是框架压根不读这一项了。
常见错误现象:input('name') 直接返回原始用户输入,前端渲染时未手动处理就导致 XSS;开发者反复检查配置、清缓存、换 PHP 版本,其实问题根本不在这儿。
- TP6 的请求数据入口统一走
think\Request,所有input()、param()、get()等函数都只是封装,底层不做自动过滤 - 如果你依赖“全局过滤”防 XSS,现在等于裸奔——哪怕开了
app_debug = false也拦不住 - 兼容性影响:TP5.1 的过滤逻辑(如
input('name', '', 'htmlspecialchars'))在 TP6 仍可用,但必须显式传参,不能靠配置兜底
用 input() 的第三个参数做单点过滤,比中间件更可控
对关键字段做针对性转义,比试图“全局拦截”更可靠。TP6 的 input() 支持第三个参数作为过滤方法,它会在取值后立即执行,且优先级高于路由/验证器中的处理。
使用场景:评论内容、用户昵称、搜索关键词等需展示在 HTML 中的字符串。
-
input('title', '', 'htmlspecialchars')—— 安全,输出前已转义,适合直接 echo -
input('content', '', 'htmlspecialchars_decode')—— 危险!这是解码,别误用 - 过滤函数必须是可调用的:字符串(内置函数名)、匿名函数、数组
['Helper', 'safeHtml'] - 注意:如果字段经过验证器(
Validate),过滤应在验证后、赋值前完成,否则验证可能误判(比如验证长度时传入的是转义后字符串)
中间件不是 XSS 防御主力,但能堵住漏网的 $_GET/$_POST 直引用
有人把中间件当“万能过滤层”,给所有请求参数套一遍 htmlspecialchars。这会导致 JSON 接口出错、富文本保存失败、API 字段被双重转义——XSS 没挡住,业务先崩了。
真正该用中间件的,是那些绕过 input() 的硬编码访问,比如直接读 $_GET['q'] 或 $request->get()['q']。
- 中间件中应只处理明确用于 HTML 渲染的 GET/POST 键,例如:
['title', 'desc', 'nickname'],而不是全量遍历$_REQUEST - 避免在中间件里修改
$request对象的原始数据,TP6 的Request是只读快照,强行改会引发不可预测行为 - 性能影响:全量过滤每个请求参数,对高频 API 是明显开销,尤其含大文本或文件上传时
模板引擎里的 {\$var} 默认不转义,{\$var|html} 才安全
很多人以为 ThinkTemplate 会像 Twig 或 Blade 那样默认转义变量,实际上 {\$name} 就是原样输出,这是 XSS 最常发生的现场。
使用场景:所有从用户输入来的变量,只要最终要进 HTML,就必须显式加过滤器。
-
{\$user['bio']}→ 危险,直接插入 DOM -
{\$user['bio']|html}→ 安全,等价于htmlspecialchars(\$user['bio']) -
{\$content|raw}仅限可信富文本,且必须配合后端白名单过滤(如使用HTMLPurifier),不能只靠模板层 - 注意:
|html不处理 JS 上下文(如onclick="alert('{\$x}')"),这种必须用json_encode或专用 JS 转义函数
最易被忽略的一点:AJAX 返回的 HTML 片段(比如用 fetch 加载评论列表),即使后端模板用了 |html,前端 JS 插入时若用 innerHTML,依然可能触发事件属性里的 XSS。这时候得靠 textContent 或严格校验响应结构。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











