PHP 8.3.36 是修复反序列化漏洞的首个正式版本,8.3.25 属未修复旧版;需升级至 8.3.36+ 并配置 allowed_classes、禁用 unserialize_callback_func 等策略方可生效。

PHP 8.3.25 是已发布的修复版本(对应厂商公告中“8.3.36版本之前的8.3.x版本受影响”,说明 8.3.25 属于未修复的旧版本),因此它本身不包含反序列化漏洞的官方修复。真正修复该问题的 PHP 8.3 系列版本是 8.3.36(发布于2026年10月23日)。若你当前运行的是 8.3.25,应升级至 8.3.36 或更高版本,再验证修复效果。
确认 PHP 版本是否已升级到位
执行以下命令,确保实际运行版本 ≥ 8.3.36:
-
php -v—— 查看 CLI 版本 -
phpinfo();(在 Web 环境中访问)—— 查看 FPM/Apache 模块版本 - 注意区分编译版本与运行时版本:某些系统存在多版本共存,需确认 Web 服务器加载的是新二进制或 SAPI 模块
检查核心修复机制是否启用
PHP 8.3.36 的修复重点并非修改 unserialize() 行为本身,而是强化了对危险类的默认限制,并配合更严格的运行时策略。需验证:
-
unserialize()调用是否启用了allowed_classes参数(推荐显式设置):unserialize($input, ['allowed_classes' => false]);→ 完全禁用对象反序列化unserialize($input, ['allowed_classes' => ['WhitelistClass1', 'WhitelistClass2']]);→ 白名单模式 - 检查 php.ini 中是否配置了全局默认值:
unserialize_callback_func = ""(应为空,禁用自动类加载回调)session.serialize_handler = php_serialize(避免旧 handler 引入兼容性风险)
构造最小化测试用例验证行为变化
使用一个含 __destruct 的可控类,观察升级前后差异:
立即学习“PHP免费学习笔记(深入)”;
<?php
class TestRCE {
public $cmd = 'echo "vulnerable"';
function __destruct() { system($this->cmd); }
}
// 构造恶意序列化字符串(仅用于测试环境!)
$payload = 'O:8:"TestRCE":1:{s:3:"cmd";s:16:"echo patched_ok";}';
echo "尝试反序列化...\n";
@unserialize($payload); // 若输出 "patched_ok",说明仍可执行 → 未生效
?>
- 在 8.3.25 环境中,该 payload 很可能成功执行
echo - 在 8.3.36+ 且配置了
allowed_classes => false时,unserialize()将直接返回false或抛出ValueError,__destruct不会触发 - 若仍执行成功,说明业务代码未启用白名单、或存在未更新的第三方组件(如旧版 Laravel、Symfony 序列化逻辑)
审计关键位置是否已适配新约束
修复生效不仅依赖 PHP 版本,更取决于应用层是否遵循安全实践:
- 搜索项目中所有
unserialize(调用,确认均传入allowed_classes参数 - 检查是否仍在使用
__wakeup()做关键校验(CVE-2016-7124 类绕过在新版中仍可能有效),建议改用__unserialize()(PHP 7.4+)进行细粒度控制 - 确认 session 数据未被攻击者污染:若 session 存储在文件或 Redis 中,且反序列化前未校验签名,即使 PHP 升级,旧 session 仍可能触发漏洞



















