应在全局中间件中调用$request->get()/post()获取原始数据并用htmlpurifier清洗,再通过mergeparam()合并到request对象,确保input()/param()后续调用返回已过滤值;禁用on*事件属性,按需配置html.allowed白名单,避免全量清洗性能损耗,且需按请求动态初始化htmlpurifier配置实例。

ThinkPHP 6 的全局中间件里怎么加 XSS 过滤
直接在 app/middleware.php 或中间件类里对请求参数做 HTMLPurifier 过滤,是无效的——因为 TP6 的中间件默认不拦截 input() 返回的数据,只处理原始 $_GET/$_POST。必须在中间件中手动重写 Request 对象的参数缓存,否则后续控制器调用 input()、param() 仍拿到未过滤的原始值。
- 在中间件
handle()方法开头,先调用$request->get()和$request->post()获取原始数据 - 用 HTMLPurifier 分别清洗 GET/POST 数组(注意保留键名结构,不能 flatten)
- 调用
$request->mergeParam($cleaned)合并清洗后的参数(TP6.1+ 支持;旧版需反射修改$request->param属性) - 不要试图在中间件里改
$_GET/$_POST全局变量——TP6 已脱离超全局依赖,改了也没用
HTMLPurifier 配置哪些选项才真正防住 XSS
开箱即用的 HTMLPurifier::getInstance() 默认只允许极简标签,会把 <img>、<a></a> 全干掉,实际业务根本没法用。关键不是“全开”或“全关”,而是控制属性白名单和事件属性剔除。
- 必须禁用所有
on*事件属性:$config->set('HTML.Attr.EnableID', false)+$config->set('HTML.SafeIframe', true)(若需 iframe) - 允许
class、src、href等安全属性,但限制src只能以http://、https://、/开头(用URI.HostBlacklist和自定义 Filter) -
HTML.Allowed别设成*,按需写死:"p,b,i,a[href|title],img[src|alt|width|height]" - 开启
Core.RemoveInvalidTags和Core.EscapeInvalidChildren,避免解析器被畸形标签绕过
为什么在控制器里用 HTMLPurifier::clean() 依然有风险
常见写法是在控制器方法里对某个字段单独过滤,比如 HTMLPurifier::clean($this->request->post('content'))。问题在于:它只清理了这一处,而 input('content')、param('content')、post('content') 在同一请求生命周期内可能被多次调用,且每次都会重新从原始未过滤数据取值——等于你洗了一次,别人又拿脏水用了。
- 如果模型验证、日志记录、缓存键生成等环节也读了同一个参数,它们拿到的仍是原始输入
- TP6 的
validate()方法默认不走中间件清洗后的参数,校验时用的是原始input() - 更隐蔽的坑:AJAX 请求带 JSON body 时,
$request->post()拿不到数据,得用$request->param(),而后者底层合并了所有输入源,清洗逻辑必须覆盖全部入口
HTMLPurifier 性能差怎么办,能不能只对特定字段过滤
HTMLPurifier 单次处理耗时约 5–20ms(视内容长度),全量清洗所有请求参数会拖慢接口。但「只过滤富文本字段」的前提是:你能 100% 确认哪些字段可能含 HTML —— 而用户完全可以把恶意脚本塞进 username 或 email 字段里提交。
- 推荐折中方案:在中间件里只清洗明确标记为「富文本」的字段,例如字段名含
_html、content、desc,其余字段走轻量正则过滤(如删<script>、<code>javascript:</script>) - 用
$request->rule()或自定义注解标记需要净化的参数,在中间件里按规则匹配键名再清洗 - 绝对不要在数据库写入前才过滤——万一中间某步把未过滤内容打到了日志、消息队列或第三方 API,就已造成泄露
最麻烦的点其实是:HTMLPurifier 的配置对象是单例,一旦在中间件里初始化一次,后续请求会复用,但不同控制器可能需要不同白名单。这时候得自己管理配置实例,按请求上下文动态 new,不然 A 用户的宽松配置会污染 B 用户的严格场景。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










