最根本的防护是禁用反序列化:全项目清除unserialize()调用,改用JSON传输;确需反序列化时严格限定白名单并校验签名;环境层禁用phar、设置unserialize_callback_func为false。

直接不反序列化用户数据,是最根本的防护方式。
彻底移除 unserialze() 的调用入口
ThinkPHP 本身在标准流程中并不主动调用 unserialize(),风险几乎全部来自开发者手动引入。必须逐项清理:
- 全项目搜索
unserialize(、->unserialize(、Str::unserialize、igbinary_unserialize(等调用 - 重点检查控制器、中间件、缓存封装、日志回放接口、调试路由等位置
- 删除所有形如
unserialize($_GET['data'])、unserialize(base64_decode(input('raw')))的代码
用 JSON 替代序列化传输
结构化数据交互应统一使用 json_encode() / json_decode($str, true):
- 前端传参改用 JSON 字符串,后端
json_decode()解析为数组 - 缓存存储时,禁用 Redis/File 驱动的
serialize => true选项,改用json_encode()存、json_decode()取 - 若需保留对象语义,可先
json_encode()再 base64 编码传输,避免序列化格式暴露类名与结构
确需兼容旧协议时,强制加白名单与签名校验
仅限极少数无法重构的历史模块:
- PHP 7.4+ 环境下,必须传
allowed_classes参数:$data = @unserialize($input, ['allowed_classes' => ['App\Model\Order', 'DateTime']]); if ($data === false) { throw new InvalidArgumentException('Invalid payload'); } - 对原始数据做 HMAC-SHA256 签名,反序列化前验证签名有效性
- 禁止允许
think\、topthink\开头的任何框架内置类进入白名单
从运行环境切断反序列化能力
- 在
php.ini中设置unserialize_callback_func = "unserialize_callback",并定义该函数始终返回false或抛异常 - 确保
phar.readonly = On,且phar不在disable_functions中(而是明确加入:disable_functions = phar_exec,phar_extract) - Web 服务器层(如 Nginx)拦截含
O:、s:、a:且参数含base64或unserialize的请求
不复杂但容易忽略



















