ThinkPHP 5.1 防止 XSS 漏洞的核心是在输入阶段开启全局过滤或输出阶段进行转义。最推荐的做法是在 application/config.php 中配置 default_filter 为 htmlspecialchars,涉及富文本编辑的场景则需引入 HTMLPurifier 库进行白名单过滤。
先说结论:ThinkPHP 5.1 可通过修改全局配置文件实现输入自动转义,富文本内容需单独使用白名单过滤库。
- 适合:所有基于 TP5.1 框架开发的 Web 应用,尤其是存在用户输入展示功能的系统。
- 优先做:在 config.php 中设置 default_filter 参数,默认开启 htmlspecialchars 转义。
- 再验证:提交含 script 标签的测试数据,确认页面源码中字符已被实体化。
命令速用版
直接修改应用配置文件即可生效,无需执行命令行工具。打开 application/config.php,找到或添加 default_filter 配置项,值为 htmlspecialchars。
return [
// 默认全局过滤方法 用逗号分隔多个
'default_filter' => 'htmlspecialchars',
// 其他配置...
];若项目包含富文本编辑器,需通过 Composer 安装过滤库:composer require ezyang/htmlpurifier。
为什么会这样
ThinkPHP 5.1 的 Request 类在获取输入参数时会自动调用配置的过滤函数。框架设计初衷是通过 default_filter 配置项统一处理输入数据,若未配置或配置不当,用户输入的恶意脚本将直接存入数据库或输出到页面。XSS 攻击本质是浏览器信任并执行了未转义的脚本代码,全局过滤能在数据进入业务逻辑前完成清洗。
分步处理
第一步:检查当前过滤配置。打开 application/config.php 文件,搜索 default_filter 键名。若不存在,手动添加该配置项,值设置为 htmlspecialchars。
第二步:处理富文本场景。若业务需要保留 HTML 标签(如文章正文),全局 htmlspecialchars 会导致标签被转义失效。此时应安装 HTMLPurifier 库,并在公共函数文件 common.php 中编写 remove_xss 函数,配置允许通过的标签白名单,如 div、p、img 等。
第三步:输出端二次确认。即便输入端已过滤,建议在视图层输出变量时使用 {$var|htmlspecialchars} 或框架自带的转义方法,确保存储型 XSS 风险被双重拦截。
怎么验证是否生效
在表单输入框中输入<script>alert(1)</script>并提交。查看数据库存储的内容,若显示为<script>则输入过滤生效。刷新展示页面,查看页面源代码,确认 script 标签未被浏览器解析执行,且页面无弹窗出现。
常见坑
全局过滤会导致 JSON 接口数据异常。若项目包含 API 接口返回 JSON 数据,default_filter 可能会破坏 JSON 格式或转义不需要处理的字段。此时建议使用 request_filter_rules 配置项针对特定字段设置过滤规则,或在控制器中单独处理 API 输入。
富文本过滤过严影响业务。HTMLPurifier 配置若未允许必要的 style 或 src 属性,会导致图片无法显示或样式丢失。需根据业务需求在配置对象中设置 HTML.Allowed 和 CSS.AllowedProperties。
常见问题
TP5.1 的 I 函数默认安全吗?
不完全安全,取决于配置。I 函数会调用 default_filter 配置的过滤方法,若 config.php 中未设置该参数或设置为空,I 函数获取的数据不会自动转义。
富文本内容如何防止 XSS?
不能使用 htmlspecialchars 直接转义。需使用 HTMLPurifier 库建立白名单机制,只允许安全的 HTML 标签和属性通过,过滤掉 script、onerror 等危险元素。
升级 TP6 后配置还有效吗?
无效,TP6 已废弃 default_filter 配置。TP6 推荐使用全局中间件或验证器 filter 方法来实现相同的输入过滤功能。
参考来源
- ThinkPHP 如何设置全局过滤规则_全局过滤规则配置【安全】
- tp5.1 防止 XSS 攻击的方法_51CTO 博客_xss 防御方法
- ThinkPHP5 XSS 漏洞修复实战:从输入过滤到输出防御的完整指南
- tp5.1 防止 xss 攻击 - xuxxnb - 博客园