修复PHP反序列化漏洞的核心是彻底移除对不可信输入的unserialize()依赖,优先替换为json_decode($input, true),并严格校验字段、类型、嵌套深度;若必须保留unserialize,则仅限PHP 7.4+下启用allowed_classes白名单(禁用框架类),同时封堵phar://协议及清理所有可控入口。

修复PHP反序列化漏洞,核心不是给 unserialize() 加参数,而是彻底移除对不可信输入的反序列化依赖。风险根源在于:只要用户能控制输入内容,且该内容被原样送入 unserialize(),就可能触发类中的 __wakeup、__destruct 等魔术方法,进而执行文件写入、命令调用等危险操作。
优先替换为 JSON 格式
JSON 天然不还原对象、不调用魔术方法,是目前最直接有效的替代方案:
- 把所有接收外部数据的入口(如 Cookie、表单隐藏字段、API 请求体)从
unserialize()改为json_decode($input, true) - 必须校验结构:限定允许的字段名、类型和取值范围(例如
theme只能是"light"或"dark",notify必须是布尔值,不能接受字符串"false") - 设置解析限制:用
json_decode($input, true, 512, JSON_THROW_ON_ERROR)控制最大嵌套深度与错误抛出,避免深度嵌套或超长输入引发异常或资源耗尽
若必须保留 unserialize,严格启用 allowed_classes 白名单
仅在无法立即迁移旧逻辑时作为临时兜底措施,但绝不能代替格式替换:
- PHP 7.4+ 才支持第二个参数,写法必须是:
unserialize($data, ['allowed_classes' => ['MySafeClass']]) - 传
false表示禁止任何类(只允许数组/标量),适合绝大多数场景;空数组[]或未指定该参数等于完全不设防 -
严禁将框架核心类(如
think\Model、Laravel\Http\Request)加入白名单——它们正是 POP 链常用跳板
封堵高危利用路径
很多漏洞不是靠直接调用 unserialize() 触发,而是通过其他函数间接激活:
- 禁用
phar://协议:在php.ini中设phar.readonly = On,并确保allow_url_include = Off - Web 服务器层拦截:Nginx 中添加规则
if ($request_uri ~* "phar://") { return 403; } - 检查缓存与 Session 驱动:ThinkPHP 的
File缓存、Memcache/Redis Session 读取若直接unserialize(),需统一替换为 JSON 或启用白名单
清理与审计关键入口
漏洞常藏在看似无害的角落,需系统性排查:
- 搜索项目中所有
unserialize(调用,重点检查来源是否可控($_GET、$_COOKIE、缓存读取、日志反解、导入文件内容) - 不要因数据存在数据库就认为可信——历史接口可能允许用户写入同一字段,需沿“写入路径 + 读取路径”双向追踪
- 确认反序列化后的对象是否参与文件操作、网络请求、命令执行等敏感行为;哪怕类本身安全,后续使用方式也可能放大风险
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











