修复PHP反序列化漏洞的核心是彻底移除对不可信输入的unserialize()调用,优先替换为json_decode($input, true),严格校验字段、类型、嵌套深度与长度,JSON失败时绝不回退unserialize;若必须保留,则仅限极窄allowed_classes白名单且禁用Phar等危险协议。

修复PHP反序列化漏洞,核心不是给unserialize()加参数,而是彻底移除对不可信输入的反序列化调用。只要用户、第三方或低权限账号能控制输入内容,哪怕加了allowed_classes,风险依然存在——因为魔术方法(如__destruct、__wakeup)仍可能被触发,尤其当白名单中混入了带危险逻辑的类。
优先替换为JSON等安全格式
把所有接收外部数据并调用unserialize()的地方,换成json_decode($input, true),前提是业务允许放弃对象还原能力。
- 只接受预定义字段:例如偏好设置只允许
nickname(字符串)、notify(布尔值)、theme(枚举值),其余字段直接拒绝 - 严格校验类型:字符串
"false"不能当作false自动转换;theme必须是"light"、"dark"之一,不能是任意字符串 - 限制嵌套深度和总长度:用
json_decode($input, true, 5, JSON_THROW_ON_ERROR)设最大5层嵌套,并捕获异常 - 失败不回退:JSON解析失败时,绝不能尝试用
unserialize()兜底——这是常见误操作,会绕过全部防护
若必须保留unserialize,强制启用allowed_classes白名单
仅适用于无法立即迁移的遗留场景,且白名单必须极窄、可验证。
- 禁止写
['allowed_classes' => true]或空数组[],这等于没限制 - 设为
false表示只允许标量和数组,最安全;但需确认业务没依赖反序列化对象 - ThinkPHP等框架组件(如
think\Model、think\Request)严禁加入白名单——它们是POP链主力 - 白名单类必须自身安全:检查其
__wakeup、__destruct是否含file_put_contents、system等危险调用
关闭Phar协议与危险流封装器
Phar反序列化是远程利用高频路径,必须从PHP配置层阻断。
立即学习“PHP免费学习笔记(深入)”;
- php.ini中设
phar.readonly = On(默认值,但旧环境常被手动关) - 设
allow_url_include = Off,禁用include("data://")类攻击 - Nginx/Apache配置中拦截可疑协议:
if ($request_uri ~* "phar://") { return 403; } - 检查代码是否调用
stream_wrapper_register()注册了自定义协议,如有则删除
清理高危调用点与会话配置
从入口出发,定位并清除所有不受控的unserialize()使用点。
- 重点检查:
$_GET/$_POST参数、Cookie值、缓存读取(如think\cache\driver\File->read())、Session驱动(Memcache/Redis读取) - Session配置加固:
session.serialize_handler统一设为php_serialize,避免php处理器的|分隔符导致的反序列化混淆 - Session存储目录权限设为
700,禁止其他用户读写 - 禁用
session.upload_progress.enabled(除非明确需要上传进度)



















