ThinkPHP反序列化漏洞修复需综合识别风险点、切断POP链、限制不可信数据参与反序列化;高危版本如TP5.0.24、TP6.1.3–8.0.4存在已知入口,应通过代码层防御、运行时白名单、架构优化等多手段协同加固。

ThinkPHP反序列化漏洞修复不能只靠“打补丁”或“升级就完事”,关键在于识别风险点、切断POP链、限制不可信数据参与反序列化过程。不同版本的入口和利用路径差异大,需结合架构版本针对性处理。
确认漏洞是否存在及影响范围
先判断是否处于高危版本区间:TP5.0.24、TP6.1.3–8.0.4均存在已知反序列化入口(如Windows.php::__destruct、Process/Pipes/Windows.php、think\Container::get()触发链等)。访问任意非法路由(如 /index.php/abc),若返回完整堆栈且含think\命名空间类名,说明APP_DEBUG=true,极可能暴露可利用的类结构。
核心修复手段:从代码层切断POP链
针对常见攻击入口,直接修改源码比依赖配置更可靠:
- 定位
thinkphp/library/think/process/pipes/Windows.php,在类末尾添加两个防御方法:
public function __sleep() { throw new \Exception('Serialization denied for '.__CLASS__); }<br>public function __wakeup() { throw new \Exception('Unserialization denied for '.__CLASS__); }立即学习“PHP免费学习笔记(深入)”;
- 检查
removeFiles()方法是否对$this->files中的元素做类型校验——若未过滤对象实例,需加入if (is_object($filename)) continue;避免调用对象析构逻辑; - 搜索项目中所有
unserialize(调用点,确保其参数来自可信来源(如固定缓存键、服务端生成token),禁止直接反序列化$_GET、$_POST、php://input等用户输入。
运行时加固:强制白名单与输入过滤
PHP 7.4+ 支持 unserialize() 的 allowed_classes 参数,必须启用:
- 将所有显式反序列化调用改为:
unserialize($data, ['allowed_classes' => ['MyCacheItem', 'MyConfigObject']]); - 若无法控制调用点(如第三方扩展),可在
php.ini中设置unserialize_callback_func并配合全局钩子拦截非法类名; - 对所有接收序列化数据的接口(如API回调、日志上报)增加前置校验:检测字符串是否以
O:、C:、a:开头,非预期格式直接拒收。
长效防护:替代方案与架构优化
从根本上降低风险,建议逐步迁移:
- 将文件缓存(File)切换为 Redis 或 Memcached 驱动,避免本地磁盘上持久化序列化内容;
- 禁用
phar://协议(在php.ini中设phar.readonly=On且移除phar扩展),阻断PHAR反序列化入口; - 在CI/CD流程中加入SAST扫描,规则覆盖
unserialize\(|__wakeup\(|__destruct\(|phar://等敏感模式,提前拦截新引入风险。



















