🔐 PHP 安全版本与维护建议

本页是 ThinkAdmin 的 PHP 安全版本唯一维护来源。更新时间:2026-10-26。

本页记录的是 PHP 引擎安全维护状态。ThinkAdmin 的 Worker 请求状态隔离修复属于应用层生命周期修复,不能替代 PHP 引擎升级。

✅ 生产版本结论

  • 生产首选:PHP 8.4.27。
  • 生产最低安全基线:PHP 8.2.35。
  • PHP 8.3 使用 8.3.36,PHP 8.5 使用 8.5.12;PHP 8.5 需要先完成 ThinkPHP、扩展和业务兼容性验证。
  • PHP 8.0、8.1 以及 PHP 7.x 仍可作为兼容性测试对象,但不应仅因版本能够安装就视为已经完成本次安全修复。
  • 项目继续保留 PHP 7.x 源码兼容目标,生产部署的安全性按照本页的包来源、补丁证据和实际验收结果单独判断。

🚨 2026-10-20 关注的两个 PHP 问题

编号影响与 ThinkAdmin 的关系
CVE-2026-109618OOM 状态损坏可能导致远程代码执行(RCE)属于 PHP 引擎状态管理问题,应用层输入限制不能替代升级
CVE-2026-109619跨请求 stale global state 可能导致释放后使用(UAF)或 RCE与常驻进程风险相关,但不能与 ThinkAdmin Worker 的路由/中间件隔离问题混为一谈

两个问题影响所有处理 Web 请求的 PHP SAPI,包括 PHP-FPM、Apache mod_php、php-cgi、FrankenPHP 和 LiteSpeed。应按 PHP 二进制、SAPI 和进程生命周期分别验收;仅验证一次 CLI,不能证明 FPM 或常驻 Worker 已加载修复后的 PHP 二进制。

📌 官方安全版本

PHP 分支官方安全版本建议证据状态
PHP 8.28.2.35生产最低安全基线官方发布版本
PHP 8.38.3.36可用支持版本官方发布版本
PHP 8.48.4.27生产首选官方发布版本
PHP 8.58.5.12兼容性验证后使用官方发布版本

上述版本均于 2026-10-23 发布,NEWS 明确列出通过 bailout 避免状态损坏的修复。生产升级时应同时核对完整包版本、SAPI、扩展 ABI 和发行版安全公告,不能只比较 PHP_VERSION 的前三段。

PHP 8.0 和 8.1 已结束官方常规维护。PHP 安全团队针对 PHP 7.4、8.0、8.1 提供了最小源码回补,供无法立即升级或自行编译的环境参考;这些分支没有对应的官方常规安全发行版,源码回补也不等同于 8.2 及以上分支的正式安全版本:

🧩 PHP 7.x 与第三方回补

PHP 7.x 不从项目源码兼容范围中删除,但官方没有提供 PHP 7.x 的常规安全发行版。PHP 7.4 另有官方最小源码回补分支;Remi 将相同修复回补到可安装的 RPM。第三方包必须按“补丁证据 + 二进制验收”判断,不按版本号推断安全状态。

分支当前可追踪的最高候选证据等级生产建议
PHP 7.4官方源码回补分支;Remi 7.4.33-31;宝塔目录 7.4.34官方源码回补;Remi 有明确 mitigation;宝塔仅有包目录优先核验 Remi 或自行按官方分支构建,宝塔包不得直接视为已修复
PHP 7.3宝塔目录 7.3.34尚未取得 CVE 补丁证据仅兼容性测试
PHP 7.2宝塔目录 7.2.35尚未取得 CVE 补丁证据仅兼容性测试
PHP 7.1宝塔目录 7.1.34尚未取得 CVE 补丁证据仅兼容性测试
PHP 7.0宝塔目录 7.0.34尚未取得 CVE 补丁证据不建议生产使用

Remi RPM

Remi 的 EL9 PHP 7.4 仓库记录了明确的回补包:

  • php-7.4.33-31.module_php.7.4.el9.remi.x86_64
  • changelog:Mitigation fix Avoid state corruption via bailout
  • changelog 明确列出 CVE-2026-109618 和 CVE-2026-109619
  • Remi PHP 7.4 包与 changelog

该包应标记为第三方 mitigation,不能写成 PHP 官方 7.4 安全发行版。官方源码回补分支只证明补丁来源,不证明任何发行版二进制已经包含修复。实际部署还必须确认 php-cli、php-fpm、php-common 及所用扩展来自同一回补集合,并完成 CLI、FPM、Worker 的独立验收。

宝塔包

宝塔软件目录能够看到以下 7.x 候选版本:7.4.34、7.3.34、7.2.35、7.1.34、7.0.34。目录存在只证明平台提供了包,不能证明包包含本次两个 CVE 的修复。

  • 宝塔 PHP 软件目录 API
  • 使用宝塔包前,必须取得包 changelog、源码差异或补丁提交、签名/SHA,并验证 CLI/FPM/Worker 三种运行方式。
  • 未取得上述证据的宝塔 PHP 7.4、7.3、7.2、7.1、7.0 版本,统一标记为尚未核验。
  • PHP 5.x 不建议用于生产环境。

🔍 包与运行环境核验

每次升级或采用第三方回补包都应记录以下信息:

  1. 发行版、仓库来源和完整包版本,例如 7.4.33-31.module_php.7.4.el9.remi。
  2. php -v、php --ini、php -m 输出,以及 CLI、FPM、Worker 实际使用的 PHP 路径。
  3. SAPI(CLI/FPM/Worker)、编译参数、扩展 ABI、包签名或 SHA256。
  4. 官方 PHPT/CVE 回归结果;应用层 Worker 状态测试单独记录,不能互相替代。
  5. 升级前后的进程 PID、重启时间和回滚包信息。

CLI 基础检查示例:

php -r 'printf("version=%s sapi=%s binary=%s\\n", PHP_VERSION, PHP_SAPI, PHP_BINARY);'
php --ini
php -m

FPM 应通过受保护的诊断入口或管理命令确认版本和 SAPI,不能用 CLI 结果代替。Worker 应在完整重启后确认新 PID、新 PHP 二进制和应用健康检查结果。

🧱 ThinkAdmin 三种运行模式

FPM

  • 升级 PHP 包后重启所有 FPM pool,确认 Nginx/Apache 指向了新 socket 或新端口。
  • 执行登录、权限、上传、Session、数据库和关键 API 回归。
  • 记录 PHP_VERSION、PHP_SAPI、扩展列表和 FPM pool 配置。

常驻 Worker

  • PHP 升级后必须完整停止并启动 Worker;只执行应用层 reload 不作为 PHP 二进制升级的充分证据。
  • ThinkAdmin Worker 的路由、中间件、Request、Session、Cookie 和数据库状态隔离测试必须单独执行。
  • 路由规则数量、Middleware 队列数量、Worker PID 和 memory_get_usage(true) 应按请求记录;规则/队列数量必须恒定,内存趋势通过压测证据判断是否存在持续线性增长。

CLI 与后台任务

  • 单独检查 Composer、迁移、队列、定时任务和命令行脚本使用的 PHP 路径。
  • FPM 或 Worker 的通过结果不能替代 CLI 验收。

🧩 与当前 ThinkAdmin 实现的对应关系

当前版本已经对常驻 Worker 做了应用层状态隔离:Worker 启动时保存四类 Middleware 队列和多应用基础状态;每次请求前恢复基线、删除 Route 容器,异常或正常结束后清理 Request 超全局、Session、Cookie、View、数据库查询计时和进程级应用标记。ThinkRequest 还会把 Workerman 的 GET、POST、Cookie、上传文件、请求头、端口、协议和原始请求体同步为 FPM 兼容的 Request/超全局输入。

这组实现解决的是应用实例在常驻进程中的请求边界问题,不能修复 PHP 引擎的 OOM 状态损坏或 stale global state。PHP 引擎升级、Worker 状态回归和官方 PHPT/CVE 回归必须分别记录。

Worker 的静态文件和返回 true 的自定义 callable 走 HttpServer::onMessage() 旁路,不进入框架请求清理流程;自定义回调如需跨请求复用对象,必须自行定义并验证状态边界。完整生命周期说明见 ThinkPlugsWorker。

🔢 环境变量数值配置

env() 返回的环境变量通常是字符串,当前配置模板对需要传给驱动或 Session 的整数项使用 PHP 原生 (int) 转换:

配置项默认值当前类型影响
SESSION_EXPIRE7200intSession 过期时间可直接传入 Worker/Session 驱动
CACHE_REDIS_PORT6379intRedis 连接端口不会以字符串传入驱动
CACHE_REDIS_SELECT0intRedis 数据库编号满足驱动参数类型

字符串 "0" 会按 PHP 原生规则转换为整数 0。MySQL hostport 等允许逗号分隔多个端口的字段继续保留字符串;其他字符串环境变量也不改变全局 env() 契约。已存在的 config/session.php 和 config/cache.php 不会被安装器覆盖,升级时需按 升级文档 手工核对并重启相关进程。

🛡️ 临时缓解措施

配置缓解只能降低暴露面,不能替代升级和补丁核验:

  • 在 Nginx/Apache/PHP 层限制解码后的请求体、multipart 部件、上传数量、请求头数量和输入变量规模;不需要上传时,可将 post_max_size 设为 8M,需要上传时可短期设为 32M,并保持 upload_max_filesize < post_max_size。
  • 不使用上传进度时,在 php.ini、FPM pool 或服务器级配置中设置 session.upload_progress.enabled=0,不能依赖 ini_set() 或 .user.ini 在请求开始后关闭。
  • PHP 8.5 可临时考虑 fatal_error_backtraces=0,仅作为应急配置。
  • FPM 可短期设置 pm.max_requests=1,以降低同一进程跨请求暴露窗口,但会增加进程创建开销。
  • 官方建议针对 OOM 路径临时使用 memory_limit=-1(应通过 FPM pool 或 Apache 的 php_admin_value 固定),但这只移除可控的 PHP 内存限制触发点,不能修复引擎;仍需评估底层分配失败和资源耗尽风险。不要使用 RLIMIT_AS 或 RLIMIT_DATA 代替修复,它们可能制造易触发的分配失败。
  • 上述配置和进程限制都不能写成正式修复,也不能替代安全版本或可追溯的回补包。
  • 采用任何临时配置后,仍须尽快升级到官方安全版本或有可追溯补丁证据的第三方包,并重启全部 FPM 和常驻 Worker。

🔁 升级、回滚与记录

  1. 在测试环境固定仓库、包版本、扩展集合和配置,先执行官方 PHPT 或供应商回归。
  2. 分别验证 CLI、FPM、Worker,确认三者加载的是同一安全包集合。
  3. 生产发布前备份当前包版本、配置、Composer 锁文件和 Worker 启动参数。
  4. 升级后重启所有 FPM pool、队列进程和 Worker,记录 PID 与健康检查结果。
  5. 出现兼容性问题时回滚到已记录的包和配置,并保留失败日志;回滚到 EOL 版本只能作为短期应急措施。

📚 证据来源