php 8.4.27 已修复两个 cvss 9.2 的内核级反序列化漏洞,但业务层仍需自查所有 unserialize() 调用,确保输入可信、设置严格 allowed_classes 白名单或优先替换为 json_decode()。

PHP 8.4.27 本身已修复两个高危反序列化漏洞(CVSS 9.2),但仅升级不能自动解决你代码里写的 unserialize() 调用。 漏洞补丁堵的是 PHP 内核级解析器的边界绕过和元数据滥用,而业务层仍可能因直接反序列化用户输入、未设白名单、或依赖危险类触发 POP 链——这些得你自己改代码。
确认你的 unserialize() 是否真在处理不可信数据
很多团队升级完就以为安全了,结果在日志分析时发现 $_GET['data']、$_COOKIE['session']、缓存读取、甚至数据库字段里还藏着裸调 unserialize() 的逻辑。只要输入来源不可控,哪怕用了 PHP 8.4.27,攻击者仍可通过构造恶意字符串触发 __wakeup()、__destruct() 或链式调用。
- 检查所有
unserialize(出现位置,重点看参数是否来自$_GET、$_POST、$_COOKIE、文件读取(如file_get_contents())、Redis/Memcacheget()返回值 - ThinkPHP 用户特别注意:
think\cache\driver\File->read()和think\session\driver\Redis->read()在旧版本中默认走unserialize(),即使升级到 TP6.3+,若驱动未显式切换为json,风险仍在 - 用
grep -r "unserialize(" ./app/ --include="*.php"快速扫一遍,别漏掉 vendor 里的第三方包(比如某些老版 Guzzle、Monolog 插件)
必须加 allowed_classes 参数,且不能填错
PHP 7.4+ 支持 unserialize($data, ['allowed_classes' => [...]]),这是目前最轻量有效的兜底手段。但填错等于没设:
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
- 填
false表示只允许数组/标量——如果你的业务确实不需要还原对象(比如只是存配置数组),这是最安全的选择 - 填空数组
[]或包含'__PHP_Incomplete_Class'等同于不设限,完全无效 - 绝对不要把
think\Model、think\Request、GuzzleHttp\Psr7\Request这类可被链式利用的类放进白名单——它们是 POP 链主力输出点 - 白名单应精确到具体业务类,例如只允许
['App\Dto\UserConfig', 'App\ValueObject\CacheKey']
优先替换为 json_decode(),别留侥幸心理
JSON 不会还原对象、不触发魔术方法、天然防 POP 链。只要你的数据结构不强依赖 PHP 对象行为(比如不需要调用 ->save() 方法),就该立刻迁移:
- 缓存场景:把
$cache->set('key', serialize($obj))改成$cache->set('key', json_encode($obj));读取时用json_decode($content, true) - Session 存储:ThinkPHP 6.3+ 可在
config/session.php中设'type' => 'json',避免走unserialize() - 如果必须保留对象行为(比如 ORM 实例),改用构造函数注入或工厂模式重建,而不是靠反序列化“复活”
禁用 phar:// 协议并拦截可疑请求
PHP 8.4.27 补丁虽修复了部分 Phar 元数据解析缺陷,但 phar:// 仍是反序列化入口高频路径。光靠 PHP 层不够,得叠加防护:
- 确认
php.ini中phar.readonly = On(默认值,但旧环境常被手动关掉) - 设
allow_url_include = Off,防止include('phar://xxx')类型利用 - Nginx 层加规则:
if ($request_uri ~* "phar://") { return 403; };Apache 可用RewriteRule "phar://" "-" [F] - 检查代码是否调用
stream_wrapper_register()注册了自定义协议(如filter://),这类注册必须删除
真正难的不是升级 PHP 版本,而是把散落在各处的 unserialize() 调用点找全、判明上下文、再决定是删、是换、还是加白名单——这个过程没有银弹,只能一行行代码对。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










