必须禁用 phar:// 协议并配置 unserialize() 白名单,php 8.5.12 不修复 phar 反序列化漏洞,仅修复两个内核级 rce;需设 phar.readonly=on、allow_url_include=off、web 服务器拦截 phar://、代码中所有 unserialize() 必须指定 allowed_classes。

phar:// 协议本身必须禁用,不是“加固”而是“切断”
PHP 8.5.12 并不修复 phar 反序列化漏洞——它只修复了两个内核级 RCE(CVE-2026-109618/19),而 phar 反序列化是应用层利用链,靠的是 phar:// 协议被允许且触发 unserialize()。所以修复动作不在 PHP 版本升级里,而在配置和代码层。
关键点:只要 phar.readonly = Off,攻击者就能构造 phar://xxx.jpg/exploit.phar,再通过 file_exists()、file_get_contents()、include() 等函数触发反序列化。这不是 bug,是设计行为。
-
phar.readonly = On(php.ini 中确认此项为On,这是默认值,但旧环境常被手动关掉) -
allow_url_include = Off(防止include('phar://...')类型调用) - Web 服务器层拦截:Nginx 中加
if ($request_uri ~* "phar://") { return 403; };Apache 加RewriteRule "phar://" - [F] - 检查代码是否注册了自定义流封装器(如
stream_wrapper_register("phar", ...)),禁止用户代码调用
unserialize() 调用点必须加 allowed_classes 白名单
PHP 8.5.12 支持 unserialize() 的 allowed_classes 参数,这是目前最轻量、最有效的兜底手段。不设这个参数,等于把 POP 链入口完全敞开。
错误写法:unserialize($input)
正确写法:unserialize($input, ['allowed_classes' => ['MySafeClass', 'MyOtherClass']])
- 业务中确实需要反序列化对象时,白名单必须精确到具体类名,不能写
['think\Model']这类高危类 - 若只处理数组/标量数据(比如缓存配置),直接设
allowed_classes => false,此时反序列化只返回__PHP_Incomplete_Class实例,无法触发魔术方法 - 空数组
[]或未传该参数,等同于不限制,毫无防护作用 - ThinkPHP、Laravel 等框架的缓存驱动默认不启用白名单,需在自定义驱动或中间件中显式覆盖
别信“升级到 8.5.12 就安全了”的误解
PHP 8.5.12 是紧急安全更新,但它修复的是 OOM 状态残留和全局状态重置缺陷(CVE-2026-109618/19),和 phar 反序列化无关。这两个漏洞影响所有 PHP 运行模式(mod_php、PHP-FPM、FrankenPHP),但它们的触发路径与 phar:// 完全不同。
修复 Core bailout 状态损坏安全问题,以及 BZ2、DOM、PDO、Opcache/JIT 内存与执行错误,改进 Unicode 字素处理、URL 解析、TLS 流状态、信号分发及会话错误处理。
换句话说:你升到 8.5.12 后,phar:// 依然能打,unserialize($_GET['data']) 依然能 RCE,只是内核层面少了一种更隐蔽的 UAF 利用方式。
- 线上环境必须同时做三件事:禁用
phar://、加固unserialize()调用、清理所有可控反序列化入口 - 尤其注意 ThinkPHP 的
think\cache\driver\File->read()和think\session\driver\Redis->read(),这些位置在 8.0.4 及更早版本中仍存在无白名单的unserialize() - 不要依赖
disable_functions屏蔽unserialize——它只是禁用函数名,不影响框架内部调用
真正该替换的不是 PHP 版本,是 unserialize() 本身
最彻底的修复,是把所有 unserialize() 替成 json_decode($data, true)。JSON 不还原对象、不触发魔术方法、天然防 POP 链,而且性能更好、可读性更强。
适用场景包括:缓存数据存储、Session 数据格式化、跨服务配置传递、前端传来的结构化参数解析。
- 前提是数据来源可信(比如你自己写的缓存写入逻辑),且不依赖对象行为(如
__toString、__get) - 如果旧系统强依赖对象反序列化(如某些 ORM 缓存),至少确保输入经过严格校验 + 白名单 + 协议隔离三层控制
- 特别注意日志反解、错误上报、调试接口等“次要路径”,它们常被忽略,却是攻击者最爱的跳板
phar 反序列化漏洞的复杂点不在技术实现,而在于它往往藏在“看起来无害”的函数调用里——file_exists()、getimagesize()、甚至 echo $obj 都可能成为触发点。防御的关键不是堵住某个函数,而是让整个链条失去立足基础:协议关掉、入口收紧、数据格式降级。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!










