PHP 安全警报:2025–2026 年度漏洞盘点与升级指南
适用范围:PHP 8.2 / 8.3 / 8.4 / 8.5
信息来源:php.net官方Changelog、php-src GitHub Security Advisories、PHP 支持版本表
一、为什么现在就要关注
PHP 在过去一年(2025.11 – 2026.10)密集发布了多个安全修复版本,涉及 30+ 个 CVE,其中包含 2 个 Critical 级远程代码执行(RCE)、多个 High 级 SQL 注入 / 堆溢出,以及一批 Moderate 级信息泄露和绕过问题。
如果你还在跑 PHP 8.1 或更早的版本——它们已经 End of Life,不再接收任何安全补丁。即使是 PHP 8.2,也将在 2026 年 12 月 31 日 结束安全支持,窗口期仅剩两个月。
二、当前 PHP 版本支持状态
| 版本 | 初始发布 | 活跃支持截止 | 安全支持截止 | 当前状态 |
|---|---|---|---|---|
| 8.2 | 2022-12-08 | 2024-12-31 | 2026-12-31 | ⚠️ 安全支持仅剩 2 个月 |
| 8.3 | 2023-11-23 | 2025-12-31 | 2027-12-31 | 🔒 安全修复阶段 |
| 8.4 | 2024-11-21 | 2026-12-31 | 2028-12-31 | ✅ 活跃支持 |
| 8.5 | 2025-11-20 | 2027-12-31 | 2029-12-31 | ✅ 最新稳定版(活跃支持) |
建议:生产环境至少升级到 PHP 8.4;新项目直接使用 PHP 8.5。
三、高危漏洞速览
以下按严重程度从高到低排列,均为 已修复 漏洞(升级到对应版本即可消除风险)。
🔴 Critical — 远程代码执行
| CVE / GHSA | 影响组件 | 修复版本 | 简述 |
|---|---|---|---|
| GHSA-w8hw-w9fx-j79w | Core | 8.5.12 | RCE via OOM corruption — 通过内存耗尽破坏 Zend 内存管理器状态,进而实现代码执行 |
| GHSA-6wmf-4rv5-p3rp | Core | 8.5.12 | RCE via stale global state — 利用过期的全局状态在错误处理路径中注入恶意执行 |
影响:攻击者可通过精心构造的请求触发内存耗尽或错误处理路径,在服务器上执行任意代码。所有启用 PHP-FPM 的公网服务都受影响。
🟠 High — SQL 注入 / 堆溢出 / 无限递归
| CVE | 影响组件 | 修复版本 | 简述 |
|---|---|---|---|
| CVE-2026-17543 | PGSQL (ext/pgsql) |
8.5.9 | SQL 注入:E'...' 转义序列中反斜杠逃逸,可注入任意 SQL |
| CVE-2026-17544 | BCMath (bccomp()) |
8.5.9 | 越界写:精心构造的操作数和 scale 参数触发堆缓冲区溢出 |
| CVE-2026-91765 | SOAP (ext/soap) |
8.5.12 | 服务端 cleanup_xml_node() 无限递归,可导致栈溢出崩溃(DoS) |
| CVE-2025-14181 | SOAP (ext/soap) |
8.5.12 | SOAP HTTP 头解析整数溢出导致缓冲区溢出 |
| CVE-2025-14179 | PDO_Firebird | 8.5.6 | SQL 注入:通过 NUL 字节绕过引号转义 |
| CVE-2025-14178 | Standard (array_merge()) |
8.5.4 | 堆缓冲区溢出:合并特殊构造的数组时越界写 |
| CVE-2026-7261 | SOAP (SOAP_PERSISTENCE_SESSION) |
8.5.6 | 请求头解析失败后 Use-After-Free |
🟡 Moderate — 信息泄露 / 验证绕过 / 越界读
| CVE | 影响组件 | 修复版本 | 简述 |
|---|---|---|---|
| CVE-2026-91768 | PHP-FPM FastCGI | 8.5.12 | IPv6 ACL 绕过:listen.allowed_clients 因部分地址比较失效 |
| CVE-2026-91769 | OpenSSL | 8.5.12 | TLS 主机名验证在 SAN 不匹配后回退到 CN,可被中间人利用 |
| CVE-2026-91767 | OpenSSL | 8.5.12 | 精心构造的服务端证书通配符 CN 导致 php_openssl_matches_wildcard_name() 堆溢出 |
| CVE-2026-91766 | HTTP Stream Wrapper | 8.5.12 | 跨域凭证泄露:HTTP 流包装器在重定向时泄露凭证到不同来源 |
| CVE-2026-93682 | HTTP Stream Wrapper | 8.5.12 | 空 Location 头重定向时越界读 |
| CVE-2026-92842 | Stream Filters (convert.*) |
8.5.12 | line-break-chars 包含 NUL 时越界读 |
| CVE-2026-14355 | OpenSSL (openssl_encrypt) |
8.5.8 | AES-WRAP-PAD 模式下 Zend 内存堆损坏 |
| CVE-2025-1218 | MySQLnd | 8.5.12 | mysqlnd 线协议中多处包越界读 |
| CVE-2026-6103 | Phar | 8.5.12 | phar_tar_number() 整数溢出,可注入 TAR 归档条目 |
| CVE-2026-6735 | PHP-FPM | 8.5.6 | FPM status 端点 XSS |
| CVE-2026-7259 | MBString | 8.5.6 | mb_ereg_search_init() 触发 php_mb_check_encoding() 空指针解引用 |
| CVE-2026-6104 | MBString | 8.5.6 | mbfl_name2encoding_ex() 越界访问 |
| CVE-2026-7568 | Standard | 8.5.6 | char 数组偏移有符号整数溢出 |
| CVE-2026-12184 | Streams | 8.5.6 | HTTPS + 代理场景下 file_get_contents() 段错误 |
| CVE-2025-14177 | Standard (getimagesize) |
8.5.4 | 内存信息泄露 |
| CVE-2025-14180 | PDO | 8.5.4 | PDO 引号转义结果空指针解引用 |
🟢 Low — 其他修复
| CVE / 修复 | 影响组件 | 修复版本 | 简述 |
|---|---|---|---|
| CVE-2026-17545 | Windows 文件 I/O | 8.5.12 | 未拒绝 Windows 保留设备名(如 CON、NUL),可导致意外文件操作 |
| CVE-2026-9672 | GD (libgd) | 8.5.9 | 升级 libgd 修复上游安全问题 |
| CVE-2026-7263 | DOM | 8.5.6 | C14N() 在 setAttributeNS() 后输出重复 xmlns 声明 |
| CVE-2026-7262 | SOAP | 8.5.6 | Apache map 值 NULL 检查缺陷 |
| CVE-2026-6722 | SOAP | 8.5.6 | SOAP_GLOBAL(ref_map) 悬垂指针 |
| CVE-2026-7258 | Standard | 8.5.6 | ctype.h 函数未一致使用 unsigned char |
| CVE-2026-7260 | Phar | 8.5.9 | 递归符号链接导致崩溃 |
| CVE-2026-44927 | URI (uriparser) | 8.5.7 | uriparser 指针差值截断为 int |
| CVE-2026-44928 | URI (uriparser) | 8.5.7 | uriparser EqualsUri 将不等 URI 误判为相等 |
| CVE-2026-42371 | URI (uriparser) | 8.5.6 | uriparser 文本范围比较数值截断 |
| CVE-2025-67899 | URI (uriparser) | 8.5.4 | uriparser 无限递归导致栈耗尽 |
四、重点漏洞深度解读
4.1 CVE-2026-17543:PostgreSQL E'...' 转义 SQL 注入
影响组件:ext/pgsql(非 PDO,直接使用 pg_query() / pg_escape_string() 的场景)
原理:PostgreSQL 的 E'...' 语法支持反斜杠转义序列(如 \'、\n)。PHP 的 pg_escape_string() 在处理此类输入时存在反斜杠逃逸缺陷,攻击者可构造特殊字符串绕过转义,注入任意 SQL 片段。
示例攻击向量:
// ❌ 危险写法(受影响)
$input = "E' OR 1=1 --";
$query = "SELECT * FROM users WHERE name = '" . pg_escape_string($conn, $input) . "'";
// 攻击者可能通过精心构造的 E'...' 序列绕过转义
修复方案:升级到 PHP 8.5.9+,或改用 PDO 预处理语句:
// ✅ 安全写法
$stmt = $pdo->prepare("SELECT * FROM users WHERE name = ?");
$stmt->execute([$input]);
4.2 CVE-2026-91769 / CVE-2026-91767:TLS 证书验证缺陷
影响组件:ext/openssl(所有使用 stream_socket_enable_crypto()、file_get_contents('https://...') 等场景)
原理:
- CVE-2026-91769:当服务器证书的 SAN(Subject Alternative Name)不匹配时,PHP 错误地回退到检查旧式 CN(Common Name)字段。这违反了 RFC 6125 的规定——SAN 不匹配应直接拒绝,而不是回退到 CN。攻击者可利用仅含 CN 匹配但 SAN 不匹配的证书实施中间人攻击。
- CVE-2026-91767:通配符证书匹配函数
php_openssl_matches_wildcard_name()在处理精心构造的通配符 CN 时发生堆缓冲区溢出,可能被恶意服务器利用。
修复方案:升级到 PHP 8.5.12+。同时建议在代码中显式设置证书验证选项:
$ctx = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'verify_depth' => 5,
'cafile' => '/etc/ssl/certs/ca-certificates.crt',
],
]);
$data = file_get_contents('https://api.example.com', false, $ctx);
4.3 CVE-2026-91766:HTTP 流包装器跨域凭证泄露
影响组件:Standard(file_get_contents('http://...')、fopen('http://...') 等内置 HTTP 客户端)
原理:当使用内置 HTTP 流包装器请求一个 URL,服务器返回 302 重定向到不同域名时,PHP 错误地将原始请求的 Authorization 头或 Cookie 泄露给重定向目标域。这违反了同源凭证隔离原则。
影响场景:
// 如果 https://internal.corp/api 返回 302 → https://evil.com/steal
// 原始请求中的 Authorization: Bearer <token> 会被发送到 evil.com
$ctx = stream_context_create([
'http' => [
'header' => "Authorization: Bearer s3cr3t-t0ken\r\n",
],
]);
$response = file_get_contents('https://internal.corp/api', false, $ctx);
修复方案:升级到 PHP 8.5.12+。临时缓解:禁用自动重定向或使用 cURL(cURL 默认不跨域转发凭证):
// 临时缓解:禁用 follow_redirect
$ctx = stream_context_create([
'http' => [
'follow_location' => 0,
'header' => "Authorization: Bearer s3cr3t-t0ken\r\n",
],
]);
// 更好的方案:使用 cURL
$ch = curl_init('https://internal.corp/api');
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Authorization: Bearer s3cr3t-t0ken']);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// cURL 不会跨域转发 Authorization 头
$response = curl_exec($ch);
4.4 CVE-2025-14178:array_merge() 堆溢出
影响组件:Standard(核心函数 array_merge()、array_merge_recursive())
原理:当合并包含特殊构造键的数组时,内部哈希表操作触发堆缓冲区越界写。理论上可被利用于内存破坏攻击。
修复方案:升级到 PHP 8.5.4+。此漏洞影响所有使用 array_merge() 处理用户输入的代码。
4.5 CVE-2026-6735:PHP-FPM Status 端点 XSS
影响组件:PHP-FPM(pm.status_path 功能)
原理:FPM 内置的状态监控端点(通常用于查看进程池状态)在输出时未对部分字段进行 HTML 转义,攻击者可通过构造特殊请求在状态页面注入 JavaScript。
影响:如果 FPM status 端点对公网开放(本就不应该),攻击者可对查看状态页的管理员实施 XSS。
修复方案:升级到 PHP 8.5.6+。同时确保 status 端点仅限内网访问:
# nginx 配置:仅允许内网 IP 访问 status
location /fpm-status {
allow 10.0.0.0/8;
allow 127.0.0.1;
deny all;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
五、升级操作指南
5.1 从源码编译升级(Linux)
# 1. 下载最新版本(以 8.5.12 为例)
wget https://www.php.net/distributions/php-8.5.12.tar.gz
tar -xzf php-8.5.12.tar.gz
cd php-8.5.12
# 2. 配置编译选项(按需调整)
./configure \
--enable-fpm \
--with-fpm-user=www-data \
--with-fpm-group=www-data \
--enable-mbstring \
--enable-opcache \
--with-pgsql \
--with-pdo-pgsql \
--with-mysqli \
--with-pdo-mysql \
--with-openssl \
--with-curl \
--with-zlib \
--enable-soap \
--enable-bcmath \
--with-gd
# 3. 编译并安装
make -j$(nproc)
make test # 可选:运行测试套件
sudo make install
# 4. 重启 PHP-FPM
sudo systemctl restart php-fpm
php -v # 确认版本
5.2 通过包管理器升级
Ubuntu / Debian(使用 ondrej PPA):
sudo add-apt-repository ppa:ondrej/php
sudo apt update
sudo apt install php8.5 php8.5-fpm php8.5-cli php8.5-pgsql php8.5-mysql \
php8.5-mbstring php8.5-curl php8.5-xml php8.5-gd php8.5-bcmath php8.5-opcache
sudo systemctl restart php8.5-fpm
CentOS / RHEL(使用 Remi 仓库):
sudo dnf install https://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf module reset php
sudo dnf module enable php:remi-8.5
sudo dnf install php php-fpm php-pgsql php-mysqlnd php-mbstring \
php-xml php-gd php-bcmath php-opcache php-pecl-zip
sudo systemctl restart php-fpm
Docker:
# 直接使用官方镜像
FROM php:8.5.12-fpm-alpine
# 安装扩展
RUN docker-php-ext-install pdo_pgsql mysqli mbstring opcache bcmath gd soap
5.3 升级后验证清单
# ✅ 确认 PHP 版本
php -v
# 预期输出:PHP 8.5.12 (cli) (built: ...)
# ✅ 确认关键扩展已加载
php -m | grep -E 'openssl|pdo|mbstring|opcache|soap|bcmath'
# ✅ 确认 FPM 正常运行
sudo systemctl status php-fpm
# 或
sudo systemctl status php8.5-fpm
# ✅ 检查 OPcache 配置
php -i | grep opcache
# ✅ 运行应用测试套件
# 如果项目有自动化测试,务必跑一遍
./vendor/bin/phpunit # PHPUnit
./vendor/bin/pest # Pest
六、安全加固最佳实践
升级只是第一步。以下措施可以进一步降低被攻击的风险:
6.1 PHP-FPM 加固
; php-fpm.conf / pool.d/www.conf
; 禁用危险函数
php_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popen,eval,assert
; 限制上传大小
php_admin_value[upload_max_filesize] = 10M
php_admin_value[post_max_size] = 15M
; 关闭暴露 PHP 版本
php_admin_flag[expose_php] = off
; 限制内存
php_admin_value[memory_limit] = 256M
; 会话安全
php_admin_value[session.cookie_httponly] = 1
php_admin_value[session.cookie_secure] = 1
php_admin_value[session.cookie_samesite] = Strict
php_admin_value[session.use_strict_mode] = 1
; open_basedir 限制(按应用路径调整)
php_admin_value[open_basedir] = /var/www/html/:/tmp/
6.2 OPcache 配置优化
; 启用 OPcache(生产环境必开)
opcache.enable = 1
opcache.enable_cli = 0
; 内存分配(按应用规模调整)
opcache.memory_consumption = 128
; 文件缓存验证(开发环境开,生产可关以提升性能)
opcache.validate_timestamps = 0
; 如果设为 0,更新代码后需重启 FPM 或调用 opcache_reset()
; JIT 编译(PHP 8.5+)
opcache.jit = tracing
opcache.jit_buffer_size = 64M
6.3 数据库安全
// ✅ 始终使用预处理语句,杜绝 SQL 注入
// PDO 方式(推荐)
$stmt = $pdo->prepare("SELECT * FROM users WHERE id = :id");
$stmt->execute([':id' => $userId]);
$user = $stmt->fetch();
// ✅ 限制数据库用户权限
// 应用使用的 DB 用户不应有 DDL 权限(CREATE/ALTER/DROP)
// 敏感操作使用独立的受限权限账户
6.4 TLS / HTTPS 安全
// ✅ 始终启用证书验证
$ctx = stream_context_create([
'ssl' => [
'verify_peer' => true,
'verify_peer_name' => true,
'min_proto_version' => STREAM_CRYPTO_PROTO_TLSv1_2,
'ciphers' => 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384',
],
]);
// ✅ 使用 cURL 替代内置 HTTP 流包装器(更安全、更可控)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS);
七、版本升级路线图
根据你当前的 PHP 版本,选择合适的升级路径:
当前版本 推荐目标 紧急程度
─────────────────────────────────────────────
PHP 7.x / 8.0 → PHP 8.5 🔴 立即(已 EOL,无安全补丁)
PHP 8.1 → PHP 8.5 🔴 立即(已 EOL)
PHP 8.2 → PHP 8.4+ 🟠 尽快(安全支持 2026-12 到期)
PHP 8.3 → PHP 8.4+ 🟡 计划中(安全支持到 2027-12)
PHP 8.4 → PHP 8.5 🟢 可选(活跃支持到 2026-12)
PHP 8.5.x (< 12) → PHP 8.5.12 🔴 立即(修复 2 个 Critical RCE)
跨大版本升级注意事项
- PHP 8.4 → 8.5:新增管道操作符
|>、#[\NoDiscard]属性、WHATWG URL API 等,向后兼容性良好。 - PHP 8.3 → 8.4:新增属性钩子(property hooks)、不对称可见性、
#[\Deprecated]属性。部分废弃行为可能触发 deprecation 警告。 - PHP 8.2 → 8.3:新增
json_validate()、Random\Engine类、Typed class constants。废弃get_class()/get_parent_class()无参调用。 - PHP 8.1 → 8.2:废弃动态属性(需
#[\AllowDynamicProperties])、废弃${var}字符串插值。
建议:升级前先在测试环境跑通全部测试用例,使用
php -l批量 lint 检查语法,关注 deprecation 警告日志。
八、总结
| 维度 | 要点 |
|---|---|
| 最紧急 | PHP 8.5.12 修复了 2 个 Critical RCE(GHSA-w8hw / GHSA-6wmf),所有 PHP 8.5 用户应立即升级 |
| 最广泛 | array_merge() 堆溢出(CVE-2025-14178)和 TLS 验证缺陷影响几乎所有 PHP 应用 |
| 最隐蔽 | HTTP 流包装器跨域凭证泄露(CVE-2026-91766)可能在不知情的情况下泄露 API Token |
| 最易修 | SQL 注入类漏洞可通过改用 PDO 预处理语句从代码层面消除 |
| 版本规划 | PHP 8.2 安全支持 2026-12 到期,应尽快迁移到 8.4+ |
安全升级不是一次性工作,而是持续的过程。建议:
- 订阅 PHP 安全公告:关注
php-src/security/advisories - 定期检查版本:至少每季度检查一次是否有新安全版本
- 自动化依赖扫描:在 CI/CD 中集成
composer audit检查依赖漏洞 - 最小权限原则:PHP-FPM 运行用户、数据库用户都应遵循最小权限
- 点赞
- 收藏
- 关注作者
评论(0)