排查php反序列化漏洞的关键是确认unserialize()是否由不可信输入驱动,整改需切断数据流、替换调用、加固环境:一、定位入口点;二、识别高危魔术方法与pop链;三、清理第三方组件风险;四、分层修复。

排查PHP反序列化漏洞,关键不是找“有没有unserialize()”,而是确认它是否被**不可信输入驱动**。只要用户能控制传给unserialize()的字符串,且该字符串未经校验就直接执行,风险就已成立。整改的核心动作是:切断可控数据流、替换危险调用、加固上下文环境。
一、快速定位所有unserialize()入口点
从代码层面锁定潜在风险位置,避免遗漏隐藏写法:
- 在项目根目录运行:grep -r "unserialize(" ./app/ ./common/ ./extend/ --include="*.php",重点关注控制器(Controller)、中间件(Middleware)和命令行指令类(Command)
- 搜索混淆变体:grep -r "base64_decode.*unserialize\|unserialize.*base64_decode" . --include="*.php",这类写法常出现在API参数解密逻辑中
- 检查所有接收用户输入的函数后是否紧跟unserialize(),例如:unserialize(input('data'))、unserialize($request->param('payload'))、unserialize($_GET['s'])
二、识别高危魔术方法与POP链触发点
反序列化本身不危险,危险的是还原对象时自动调用的魔术方法。需人工确认是否存在可被串联利用的敏感行为:
- 全局搜索__destruct、__wakeup、__toString、__call等方法定义,尤其关注其中是否包含file_put_contents、system、include、call_user_func等敏感操作
- 检查是否引入了已知危险类,如ThinkPHP 5.1.31中的think\process\pipes\Windows(CVE-2018-20062),搜索new Windows(或use Windows
- 查看模型类或自定义类是否重写了__toString()且未做类型约束,可能被用于触发Conversion链或文件读取
三、清理第三方组件与配置带来的隐式风险
很多反序列化入口不在主业务代码里,而藏在扩展、缓存或Session配置中:
- 检查config/cache.php中是否设置了'serialize' => true,尤其是type => 'file'或type => 'redis'场景,这会让缓存数据成为反序列化通道
- 查看composer.json是否引入旧版组件(如topthink/think-cache v1.x),它们可能在get()方法中无校验地调用unserialize()
- 搜索vendor/下是否有自定义Session处理器或日志驱动,确认其read()或write()方法是否直接反序列化存储内容
四、代码整改的三类有效方案
修复不能只删一行代码,要分层阻断攻击路径:
- 替换方案:将unserialize()全部改为json_decode()(配合JSON_OBJECT_AS_ARRAY)或igbinary_unserialize()(需服务端统一启用且不对外暴露)
- 校验方案:若必须保留unserialize(),则严格限制输入来源,例如仅允许来自内部可信队列、加签验证的JWT载荷,或对base64字符串做SHA256比对
- 隔离方案:禁用危险魔术方法的自动触发——在php.ini中设置unserialize_callback_func = "",并确保error_reporting关闭调试信息泄露
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











