> ## Documentation Index
> Fetch the complete documentation index at: https://doc.lwops.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# PHP远程代码执行漏洞缓解方案

CVE-2026-109619（跨请求状态残留 UAF）与 CVE-2026-109618（OOM longjmp 无效状态消费）

<table>
  <colgroup>
    <col width="146" />

    <col width="114" />

    <col width="100" />

    <col width="214" />
  </colgroup>

  <thead>
    <tr>
      <th>风险等级</th>
      <th>发布日期</th>
      <th>文档版本</th>
      <th>适用范围</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>严重 Critical</td>
      <td>2026.10.22</td>
      <td>V1.0</td>
      <td>所有运行受影响 PHP</td>
    </tr>
  </tbody>
</table>

## 1. 漏洞描述

### 1.1 CVE-2026-109619　跨请求全局状态残留导致释放后使用（UAF）

PHP worker 进程保留的部分全局状态（错误、会话、对象与扩展状态）可能指向某个请求独享的内存。正常流程会在请求内存释放前重置这些状态；但致命错误（解析/编译失败、未捕获 Error、require 失败、最大执行时间超时、OOM 等）可能使操作中断、跳过配对的重置，或关闭阶段的新告警在状态清理后重新写入。请求堆随后被释放，而 worker 的全局字段仍指向它。

利用需要生产者 + 消费者两个请求命中同一 worker：生产者把请求独享状态发布到全局位置；后续请求在正常初始化之前的某个操作读取/释放/分支该悬垂状态（已确认的两类消费者：初始化前的 INI 诊断、会话上传进度处理）。精心构造堆布局可实现完整 RCE。

* 已确认案例 A（PHP 8.5）：开启 fatal\_error\_backtraces 时，致命错误的回溯状态始终错过关闭阶段重置 ——mod\_php 已确认 RCE 的基础路径。
* 已确认案例 B：会话上传进度（session upload progress，默认启用，无需应用调用 session\_start() ）在正常初始化前即可触碰会话/解码器状态 —— mod\_php 与 FPM 均已验证 RCE。

### 1.2 CVE-2026-109618 OOM longjmp 使请求内存处于无效状态

PHP 对内存耗尽（OOM）使用 longjmp() 跳出当前上下文。某些上下文中请求内存在完全初始化前即暂时可达，此时任一分配失败（无需与无效内存相关）都会经 longjmp 提前退出，使请求内存处于无效状态；请求关闭流程随后读取或据此分支。多种 OOM 策略可稳定触发并导致 RCE。

* 无可用地声明 Content-Length 的 multipart 请求可通过 post\_max\_size 初始检查后持续供给解码数据；
* 单个 multipart part 可含无限多头部，PHP 内部表示的内存开销远大于线上体积，可在 post\_max\_size 之内耗尽memory\_limit；
* 空文件控件不计入 max\_file\_uploads 但仍生成完整元数据数组，嵌套字段名成倍放大开销。

> [!NOTE]
>
> 利用前提
>
> 1. 先用利用CVE-2026-109618触发OOM
> 2. 再利用CVE-2026-109619实现攻击
> 3. OOM生产者与OOM消费者请求必须命中同一worker。
> 4. 攻击命中前，worker未被回收过。

## 2. 缓解措施

全局配置 (php.ini)

<table>
  <colgroup>
    <col width="248" />

    <col width="160" />

    <col width="310" />
  </colgroup>

  <thead>
    <tr>
      <th>措施</th>
      <th>针对</th>
      <th>要点</th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td>memory\_limit = -1</td>
      <td>CVE-2026-109618</td>
      <td>通过避免可预测的OOM路径来阻断击。</td>
    </tr>

    <tr>
      <td>max\_input\_nesting\_level = 16</td>
      <td>CVE-2026-109618</td>
      <td>限制外部输入变量的最大嵌套深度，安全加固。</td>
    </tr>

    <tr>
      <td>max\_file\_uploads = 8</td>
      <td>CVE-2026-109618</td>
      <td>单次请求中允许同时上传的最大文件数量，安全加固。</td>
    </tr>

    <tr>
      <td>post\_max\_size</td>
      <td>CVE-2026-109618</td>
      <td>限制上传文件的大小，该配置影响在线升级功能，可在需要时临时调整回来。</td>
    </tr>

    <tr>
      <td>session.upload\_progress.enabled= 0</td>
      <td>CVE-2026-109619</td>
      <td>阻断已验证的早期会话生产者/消费者。</td>
    </tr>
  </tbody>
</table>

> [!TIP]
>
> ⚠ memory\_limit = -1 的
>
> 把 memory\_limit 设为 -1（无限制），并不会改变原本脚本的内存占用行为，页面加载速度、CPU 占用、响应时间都不会因此变快或变慢，但系统失去了对失控脚本的最后一道软性约束，极端情况下可能触发系统级 OOM Killer。

## 3. 配置示例

php.ini：

```text theme={null}
; ===== 缓解：CVE-2026-109618 / CVE-2026-109619 =====; 移除每请求可预测内存上限，破坏“可控 OOM”利用前提。memory_limit = -1
; 收紧输入面（
post_max_size = 32M
max
_
input_nesting_level = 16
max
_
file_uploads = 8
; 阻断“会话上传进度”早期生产者/消费者session.upload_progress.enabled = 0
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.