PHP 8.3.35存在未修复的CVE-2026-109618/109619漏洞,unserialize()调用不受控数据可触发php2shell远程代码执行;官方修复版为8.3.36,须立即升级并清理所有unserialize()调用点。

unserialize() 是 PHP 中高危函数,尤其在 PHP 8.3.35 这个未修复 CVE-2026-109618/109619 的版本中,一旦反序列化不受控数据(如 $_GET、$_COOKIE、文件内容、缓存值),攻击者可直接触发 PHP2Shell 漏洞实现远程代码执行——无需登录、不依赖框架、绕过常规 WAF。
你当前用的是 8.3.35,而官方修复版是 8.3.36(2026年10月21日发布)。在升级前,必须快速定位并清理所有潜在的 unserialize() 调用点。
一、用 grep 快速扫描全项目
终端进入项目根目录后运行:
grep -r "\bunserialize\s*(" --include="*.php" . | grep -v "vendor/" | grep -v "tests/"
说明:
-
\bunserialize\s*(匹配函数名+空格+左括号,避免误匹配注释或变量名(如my_unserialize_func) -
--include="*.php"只扫 PHP 文件 -
grep -v "vendor/"排除第三方库(先聚焦你写的代码) -
grep -v "tests/"暂时跳过测试文件(它们通常不进生产)
看到类似结果就需人工核查:
includes/cache.php: $data = unserialize($cache_content); api/v1/user.php: $payload = unserialize(base64_decode($_GET['data']));
二、重点盯防的“伪装调用”模式
有些代码不会直写 unserialize(),但等效危险。查这些:
-
unserialize(...)的变体写法:-
@unserialize(...)(错误抑制不等于安全) $func = 'unserialize'; $func($data);call_user_func('unserialize', $data)
-
- 反序列化入口常藏在:
-
$_GET['data']、$_POST['payload']、$_COOKIE['session'] - 文件读取后直接传入:
unserialize(file_get_contents('/tmp/cache.bin')) - Redis/Memcached 取出的值未校验就反序列化
-
- 第三方组件里可能隐含调用(如旧版
phpFastCache、自定义 Session 处理器)
建议顺手加一行检查:
grep -r "\$_(GET\|POST\|COOKIE)\[" --include="*.php" . | grep -i "unserialize\|base64_decode"
三、用 PHPStan 或 Psalm 做静态分析(进阶)
如果你项目已接入类型分析工具,可快速发现危险链:
- 安装 PHPStan 扩展
phpstan/phpstan-phpunit后,加自定义规则检测unserialize()参数是否来自超全局变量。 - 或用 Psalm 的
TaintedInput插件(需配置taintAnalysis: true),它会标出:Argument 1 of unserialize expects string, string (tainted) provided
这类提示比 grep 更精准,能识别变量传递路径(比如 $_GET → $x → $y → unserialize($y))。
四、临时缓解:打补丁式拦截(上线前应急)
如果无法立刻删掉所有 unserialize(),可在项目入口(如 index.php 顶部)加一层防御:
if (function_exists('unserialize')) {
$original_unserialize = 'unserialize';
function unserialize($data, $options = []) {
// 拦截明显恶意特征(非万能,但可挡批量扫描)
if (preg_match('/^\s*O:\d+:"[^"]+":/', $data)) {
error_log("[BLOCKED] unserialize attempt with object payload: " . substr($data, 0, 100));
throw new RuntimeException('Unserialize blocked for security');
}
return $original_unserialize($data, $options);
}
}
⚠️ 注意:这只是临时兜底手段,不能替代升级和代码清理。PHP2Shell 的 PoC 已公开,绕过这种正则非常容易。
升级到 8.3.36 是根本解法。现在就执行:
# 如用 apt sudo apt update && sudo apt install php8.3 # 如用 brew(macOS) brew upgrade php@8.3 # 如用源码编译,请确认 configure 后 make install 的版本是 8.3.36 php -v # 必须输出 8.3.36 或更高
不升级,只改代码,风险仍在。漏洞利用链已成熟,扫描器 24 小时在线。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











