PHP 8.5.7:几个值得留意的漏洞修复

2026-06-05 22 预计阅读时间:1 分钟
来源:oschina.net AI 摘要 原文链接

免责声明:本文为 AI 摘要整理,建议结合原文阅读。摘要可能省略上下文、版本差异或边界条件,不作为官方说明。

预计阅读时间:7 分钟

PHP 8.5 系列的第七个补丁版本发布了。版本号看着不起眼,但里面修了几个能直接踩到的坑——getopt() 行为异常、日期计算溢出、DOM XPath 自定义函数的内存安全问题,以及 Opcache 在特定调用场景下的 VM 处理缺陷。如果你已经在跑 PHP 8.5,这版值得尽快跟进。

getopt() 可选值解析修复(GH-21901)

CLI 场景下 getopt() 对"可选值"参数的处理出了偏差。所谓可选值,就是参数声明为 v::——有值就取值,没值也不报错。修复前,某些传值方式会被误判为"没有值",导致脚本拿到的结果和预期不一致。

举个例子,下面这段脚本在修复前后行为可能不同:

// cli_test.php
$options = getopt('v::');

if (isset($options['v'])) {
    echo "v 的值: " . ($options['v'] === false ? '(无值)' : $options['v']) . "\n";
} else {
    echo "v 未出现\n";
}

运行方式与预期结果的对照:

# 传了显式值
php cli_test.php -vhello
# → 期望: v 的值: hello

# 只给选项不给值
php cli_test.php -v
# → 期望: v 的值: (无值)   (v:: 声明下,无值时返回 false)

# 不传该选项
php cli_test.php
# → 期望: v 未出现

在旧版本中,第二种情况可能被错误地当作"选项未出现"处理,逻辑分支直接走偏。如果你的 CLI 工具依赖可选值参数做条件判断,升级后建议跑一遍单元测试确认行为一致。

日期计算的整数溢出(GH-18422)

php_date_llabs 是 PHP 日期扩展内部做绝对值计算的函数。当输入是极小的负整数(接近 LLONG_MIN)时,取绝对值会溢出——因为 LLONG_MIN 的绝对值无法用同宽度整数表示。

日常业务不太会碰到这个边界,但如果你在做长时间跨度的时间差计算(比如历史日期回溯、天文历法转换),传入极端负值就可能触发错误结果甚至段错误。修复后这类边界输入会得到正确处理。

简单验证脚本:

// date_overflow_test.php
try {
    // 极端负值时间戳(仅做边界探测,日常不会用到)
    $ts = new DateTime('@' . PHP_INT_MIN);
    echo "DateTime 构造成功: " . $ts->format('Y-m-d H:i:s') . "\n";
} catch (Exception $e) {
    echo "异常: " . $e->getMessage() . "\n";
}

升级后运行这段脚本,确认不再出现异常输出或崩溃即可。

DOM XPath 自定义函数的 UAF(GH-22077)

这个修复涉及内存安全。DOM 扩展允许你用 xpath_register_php_functions() 把 PHP 函数注册为 XPath 调用目标。在特定执行路径下,内部对象引用的生命周期管理出了问题——Use-After-Free,意味着一个已释放的内存地址被再次访问。

UAF 漏洞在 Web 场景下有被利用的风险,尤其是允许用户输入构造 XPath 查询的应用。如果你的项目用到了自定义 XPath 函数,这个修复是升级的硬性理由。

典型使用模式(升级后应重新验证):

// xpath_custom_test.php
$dom = new DOMDocument();
$dom->loadXML('<root><item status="active">A</item><item status="inactive">B</item></root>');

$xpath = new DOMXPath($dom);
// 注册 PHP 函数供 XPath 调用
$xpath->registerNamespace('php', 'http://php.net/xpath');
$xpath->registerPhpFunctions('strtolower');

// 在 XPath 中调用 PHP 函数
$nodes = $xpath->query('//item[php:functionString("strtolower", @status) = "active"]');
foreach ($nodes as $node) {
    echo "匹配节点: " . $node->textContent . "\n";
}

升级后跑一遍这类逻辑,确保查询结果稳定、无异常退出。

Opcache VM 观察机制下的修复

摘要中提到的 Opcache 修复,涉及"observed user function call"期间 VM 的处理。Opcache 的观察模式(observation)用于追踪函数调用行为以优化后续编译。在观察过程中如果 VM 状态处理不当,可能导致优化后的代码路径与实际执行不一致,表现为难以复现的偶发错误。

这类问题通常在高压环境或特定调用链组合下才会暴露,但一旦触发,调试成本很高。升级是最经济的应对方式。

升级操作与检查清单

# 从源码编译升级(以常见 Linux 环境为例)
cd /usr/local/src
wget https://www.php.net/distributions/php-8.5.7.tar.gz
tar xf php-8.5.7.tar.gz
cd php-8.5.7

# 建议沿用你之前的 configure 参数,避免遗漏扩展
# 可以从旧版本 phpinfo 中提取 configure line
./configure $(cat /usr/local/src/php-8.5.6-configure-args.txt)
make -j$(nproc)
make test   # 重点跑 ext/date、ext/dom、ext/opcache 相关测试
sudo make install

# 重启服务
sudo systemctl restart php-fpm
sudo systemctl restart apache2  # 或 nginx,视你的 SAPI 而定

升级后逐项确认:

  • CLI 工具:跑一遍依赖 getopt() 可选值的脚本,确认参数解析结果与预期一致。
  • 日期边界:如果项目有极端时间戳处理,做一轮边界值测试。
  • DOM XPath:对使用了 registerPhpFunctions() 的查询逻辑做回归验证。
  • Opcache:观察生产环境错误日志,留意是否有新出现的偶发异常;如有,可临时用 opcache.opt_debug_level=0x10000 输出优化信息辅助排查。

PHP 8.5.7 是纯修复版本,没有新特性,也没有破坏性变更。升级风险低,但上面几个 bug 的影响面因项目而异——用到的就修,没用到也安心。建议所有 8.5 用户跟进,至少把 UAF 风险堵上。


相关推荐