Skip to content
Exploit for CVE-2026

Exploit for CVE-2026

Sploitus • October 21, 2026

**Scope:** Multiple public-facing PHP sites (web applications, CMSs, e-commerce sites and custom applications), including Apache, Nginx, PHP-FPM, containers and older PHP runtimes.

**Vulnerabilities:** CVE-2026-109618 and CVE-2026-109619 (critical unauthenticated RCE and potential process-memory disclosure).

> **Urgent:** PHP says **no configuration or WAF workaround is a complete mitigation**. Upgrade PHP to a fixed build as soon as possible. If a vulnerable internet-facing service cannot be patched and sufficient risk reduction cannot be demonstrated, restrict its audience or take it offline. A working website is not proof that it is safe.

These are **PHP runtime vulnerabilities**, not merely WordPress, Drupal or Joomla bugs. Even simple PHP websites can be exposed. Check every *web-serving* PHP runtime, including separately installed FPM services, Apache `mod_php`, `php-cgi`, LiteSpeed, FrankenPHP, containers, third-party appliances and vendor-provided binaries. The command-line PHP version may differ from the version serving web traffic.

| PHP branch | Upstream fixed release | What to do |

| 8.5 | **8.5.12** | Upgrade or install verified vendor backport |

| 8.4 | **8.4.27** | Upgrade or install verified vendor backport |

| 8.3 | **8.3.36** | Upgrade or install verified vendor backport |

| 8.2 | **8.2.35** | Upgrade or install verified vendor backport |

| 8.1 and earlier | No normal upstream maintained release | Obtain trustworthy distro/LTS backport or migrate; PHP security team provides minimal source backports for **7.4, 8.0 and 8.1** |

**Important:** Distribution packages may keep an older-looking PHP version number while backporting the fix. Verify the package's **security changelog/advisory and installed build**, not just `php -v`.

- **CVE-2026-109618:** out-of-memory (OOM) handling can corrupt partially initialized request state. Disabling session upload progress does **not** fully mitigate this issue.

- **CVE-2026-109619:** stale request/global state after memory is freed, potentially affecting later requests in a worker. Disabling session upload progress blocks a known path but **not every variant**.

## 2. Immediate plan if websites must remain online

| Priority | Action | Can service stay online? | Limitations |

| **P0** | Identify externally accessible PHP websites and responsible owners; patch internet-facing sites first | Yes | Inventory must cover nonstandard installs/containers |

| **P0** | Roll patched PHP packages onto one pool/node at a time behind a load balancer | Usually | Drain traffic, test, replace workers, confirm active versions |

| **P0** | Where patching is delayed, use **both** PHP vendor-recommended temporary controls below | Usually | Reduces known attack paths; **not a fix** |

| **P0** | Restrict legacy or administrative applications to VPN, trusted IP ranges or authenticated reverse proxy | Yes for authorized users | Public access may be reduced |

| **P1** | Enable managed WAF protections, rate/size limits and targeted multipart controls | Usually | WAF can be bypassed and may break uploads |

| **P1** | Limit PHP service accounts, file writes, database permissions and outbound access | Yes, after testing | Controls impact, not exploitation itself |

| **P1** | Monitor logs, worker crashes, suspicious processes, file changes and outbound traffic | Yes | Detection is not prevention |

### Temporary PHP settings, **not** a substitute for patching

Apply to each relevant *web-serving* PHP SAPI and restart all affected workers. Prefer administrator-controlled settings that individual applications cannot override.

; Temporary risk reduction; carefully assess potential resource exhaustion.

; Choose based on actual application requirements:

; For upload-dependent sites, a carefully tested 32M may be appropriate.

; Keep upload_max_filesize below post_max_size.

Where feasible enforce `memory_limit=-1` as an admin setting. **Trade-off:** removing the PHP memory cap may raise denial-of-service/host exhaustion risk. Use OS/container cgroup memory limits and worker isolation, not `RLIMIT_AS` or `RLIMIT_DATA` (which can reproduce an allocation-failure path). Limit decoded request bodies, multipart parts, fields, headers and nesting at the proxy/WAF, including chunked requests without usable `Content-Length`.

**For CVE-2026-109619 (stale state path):**

Restart **every** worker after setting these. These settings block demonstrated paths, not all potential variants. Fix attacker-reachable fatal errors/timeouts and incorrect per-request PHP directives; hiding error messages does not remove the underlying issue. Normal file uploading generally remains available when upload-progress *tracking* is disabled, but applications relying on progress reporting need testing.

**PHP-FPM pool example** (path varies by OS/version):

php_admin_flag[session.upload_progress.enabled] = off

; php_admin_flag[fatal_error_backtraces] = off

Do not assume `.user.ini` or runtime `ini_set()` takes effect early enough to prevent the issue. For Apache mod_php, apply corresponding administrator-controlled `php_admin_value`/`php_admin_flag` in server or virtual-host configuration, **not** `.htaccess` overrides. Back up configurations, test syntax, and gracefully replace or restart workers; merely reloading a web proxy does not necessarily recycle PHP workers.

1. **Preferred:** enable the current managed emergency rules from your CDN/WAF/security vendor (Cloudflare, Akamai, Fastly, Imperva, ModSecurity/OWASP CRS, etc.), confirm they apply to the actual origin, and monitor legitimate-traffic impact.

2. **Apache with ModSecurity:** use request-body inspection and a tested rule to block the `PHP_SESSION_UPLOAD_PROGRESS` form field as *one* additional barrier. Example below; validate parsing and `SecRequestBodyAccess On` before relying on it:

SecRule ARGS_NAMES "@streq PHP_SESSION_UPLOAD_PROGRESS" \

"id:1026109618,phase:2,t:none,deny,status:403,log,msg:'Blocked PHP upload progress field'"

3. **Apache without ModSecurity:** selectively deny multipart POSTs in vhosts/paths that never need uploads. Example in server/vhost context (also suitable for supported rewrite contexts after testing):

RewriteCond %{REQUEST_METHOD} ^(POST|PUT|PATCH)$ [NC]

RewriteCond %{HTTP:Content-Type} ^[[:space:]]*multipart/form-data([;,[:space:]]|$) [NC]

4. **Nginx:** there is **no Nginx-only fix** for PHP memory corruption. Apply the PHP settings/patch to the FPM backend. Use `client_max_body_size` scoped to each application; block multipart methods on sites without uploads using a **tested** vhost/location rule or WAF; preserve required upload and form functionality. Example request-size constraint:

5. **Cloudflare/CDN:** enable emergency managed protections; if using custom rules, test multipart/form-body inspection and exclusions for real upload endpoints. Do **not** indiscriminately block `PHPSESSID`: that breaks sessions but does not repair PHP.

6. **Origin protection:** restrict direct origin access to the proxy/CDN where practical, otherwise attackers can bypass front-door WAF protections.

**Note:** Blocking multipart forms or a specific parameter only covers known request shapes. It is **not** reliable protection against both CVEs.

Use approved package repositories, vendor advisories and change controls. **Do not assume the newest available package is fixed without reviewing its changelog.** On multi-site hosts, inventory *each* PHP branch and FPM socket/pool.

| Environment | Practical patch approach | Operational notes |

| **Debian/Ubuntu** | `sudo apt update && apt list --upgradable`; install the vendor's security-fixed `phpX.Y-fpm`, `phpX.Y-cli` and relevant extensions (or distribution `php` packages). | `apt-cache policy phpX.Y-fpm`; `apt changelog phpX.Y-fpm`; restart matching `phpX.Y-fpm` and web-facing Apache if applicable. Ubuntu Pro/ESM may provide older-version fixes; confirm notice. |

| **RHEL/Rocky/Alma/Oracle** | `sudo dnf updateinfo list --security`; `sudo dnf upgrade --security`; inspect PHP/AppStream and third-party repositories. | `rpm -q --changelog `; check Red Hat/Rocky/Alma/vendor advisory. Restart actual `php-fpm`/`httpd` units. |

| **SUSE** | `sudo zypper lp` and apply relevant vendor PHP security patches | Validate installed patch and recycle web PHP workers. |

| **Windows / IIS FastCGI** | Replace PHP binary with security-fixed signed vendor build; inspect multiple `php-cgi.exe` locations | Recycle the associated IIS application pools; verify effective loaded binary. |

| **Docker/Kubernetes** | Pull a new **fixed** base image digest, rebuild application image and redeploy | Don't rely on `docker exec apt upgrade` as a permanent fix. Drain/update replicas; scan deployed image and runtime. |

| **cPanel/Plesk / managed hosting** | Use hosting vendor's PHP selector/update tools and advisories | provider for exact PHP builds, backports and ETA; check every hosted site. |

| **Custom-built / legacy PHP** | Prefer tested vendor/LTS packages. PHP security team supplies minimal source backports for PHP 7.4/8.0/8.1 | Build in staging with exact source/configuration; review patch provenance, integration tests, rollback. Do not run a third-party patch script blindly on production. |

| **FrankenPHP, LiteSpeed and bundled appliances** | Update the embedded/runtime PHP through their vendor image or package | Confirm actual runtime and vendor fix, not merely web-server version. |

**Quick inventory (Linux, adjust service names):**

php -v # CLI only; not proof of web version

ps -eo pid,user,comm,args | grep -E '[p]hp-fpm|[a]pache2|[h]ttpd|[l]sphp|[p]hp-cgi'

systemctl list-units --type=service | grep -Ei 'php|apache|httpd|nginx|lsws'

find /etc/php /opt /usr/local -name 'php.ini' 2>/dev/null

Verify `phpinfo()` or equivalent **privately**, via an authenticated test route, then remove the test page; never leave public environment disclosure exposed. Record site → public hostname → load balancer/backend → SAPI/version/build → pool/config → owner → remediation status. For each patched pool, confirm **new workers** actually serve requests and no old backend remains in rotation.

## 5. When a critical service cannot be changed today

- **Make a temporary exception formally:** identify accountable application owner, reason for delay, mitigation owner and shortest feasible patch deadline.

- **Reduce reachability:** keep the site online for authorized users behind VPN, identity-aware proxy or IP allowlist if feasible; separate public informational pages from vulnerable dynamic functions.

- **Protect data:** isolate PHP service identities, use read-only web roots where possible, remove unnecessary write permissions, reduce database privileges, deny needless outbound egress and block lateral access from web DMZ to internal networks.

- **Segment hosting:** isolate legacy websites from sensitive production systems; avoid dozens of unrelated tenants sharing one PHP account or writable filesystem.

- **Increase visibility:** preserve reverse-proxy, WAF, web server, FPM and OS audit logs; monitor unexpected PHP-worker child processes (`sh`, `bash`, `curl`, `wget`, PowerShell), worker crashes, unusual requests and filesystem changes. Preserve incident evidence before cleanup.

- **Escalate if exposed:** if controls cannot sufficiently lower risk, prioritize a partial outage/restricted service rather than leaving an unpatched open public endpoint indefinitely.

## 6. Safe change sequence and validation

1. **Inventory and triage:** publicly accessible, internet-facing `mod_php`, personal data, authentication and multi-tenant hosts get highest priority.

2. **Back up** configuration and runtime packages/images. Stage one representative app, including login, uploads, forms and CMS plugins.

3. **Deploy temporary controls** to each PHP runtime/pool and WAF, then reload/restart affected PHP worker processes. Confirm settings in the *effective web SAPI*, not only CLI.

4. **Patch** from official PHP/distro/vendor sources. On clustered sites drain one node, update/recreate workers, perform application smoke tests, then return it to service and repeat.

5. **Confirm** exact release or distro security backport, active runtime, FPM process start time, functionality, proxy behavior and error rate. Do not run an untrusted public PoC against production.

6. **Hunt for compromise:** review historical activity from before the patch; unexpected worker child processes, unusual file writes, new admin users, malicious scheduled tasks, outbound connections and PHP webshells. A successful patch does **not** remove a prior compromise. If indicated, isolate, investigate, rebuild from trusted images and rotate affected secrets.

7. **Track completion:** record evidence for each hostname/pool; retire temporary risky settings after the validated fix and regression testing, subject to normal hardening policy.

## Sources and verification (21 October 2026)

- **Primary authoritative guidance:**

- PHP source/release downloads:

- CVE-2026-109618 advisory:

- CVE-2026-109619 advisory:

- UK NCSC emergency guidance:

- Research/repository supplied:

- Additional researcher analysis:

**Source caution:** The supplied community GitHub repository includes scripts, patches and sample WAF rules. These may help with response planning but are **not** a substitute for the official PHP advisory, authenticated vendor backports or engineering review. In particular, that repository's emphasis on `session.upload_progress.enabled=Off` does **not** cover all attack paths; the PHP project additionally identifies the OOM path and states that only patching is complete protection.

This package includes `php2shell_monitor.py`, a small Linux/Python monitoring aid for the visibility activities described in Sections 5 and 6. It performs read-only inspection of processes, effective PHP CLI configuration and selected web roots. It does **not** probe websites, exploit either CVE, patch PHP, edit application files, quarantine content, terminate processes or restart services.

The monitor is an additional detection signal—not a mitigation, an endpoint security product or proof that a server is clean. Scheduled process snapshots can miss short-lived activity. For durable process visibility, use an EDR, Linux Audit, eBPF or another continuous telemetry source where available.

- Linux `/proc` for suspicious direct children of configured PHP or web-worker processes, including shells, interpreters and common transfer tools.

- Each configured PHP CLI binary for `session.upload_progress.enabled`. CLI results may differ from PHP-FPM, Apache `mod_php`, CGI, LiteSpeed or FrankenPHP configuration.

- Recently modified PHP-like files in configured web roots, using configurable content indicators and SHA-256 hashes.

- Optional SMTP alerts with cooldown-based duplicate suppression.

Findings are heuristic. Legitimate applications may invoke utilities or contain functions such as `base64_decode`, `eval`, `system` or `proc_open`. Correlate alerts with trusted deployment artifacts, package records, access logs, process/network telemetry and application-owner knowledge.

- Python 3.8 or newer; no third-party Python packages

- Read permission for relevant processes, PHP binaries and web roots

| `php2shell_monitor.py` | Standalone monitor |

| `php2shell-monitor.ini` | Sample configuration and tuning options |

| `php2shell-monitor.service` | Hardened one-shot systemd unit |

| `php2shell-monitor.timer` | One-minute systemd schedule |

| `SHA256SUMS` | Package-file integrity hashes |

Review `php2shell-monitor.ini` and set `web_roots` and `php_binaries` for the actual server. Run without `sudo` first:

`--dry-run` prevents email delivery and state-file updates. The inspection remains read-only even without it; normal mode may write only the configured monitor state/log and send configured email. Use `sudo` only if the chosen account cannot read the relevant processes or files. Protect output because process command lines and paths may contain sensitive data.

| `1` | Completed with one or more findings |

| `3` | Email delivery or state update failed |

An exit code of `1` is an alert condition, not a monitor crash.

1. List every relevant PHP binary in `php_binaries`. Remember that a CLI check does not establish the effective setting of a web SAPI.

2. List only intended application roots in `web_roots`; broad roots increase runtime and false positives.

3. Tune `exclude_paths`, `lookback_minutes`, `minimum_indicator_matches` and expected child processes in staging.

4. Keep email disabled until initial findings have been reviewed. If SMTP authentication is used, supply the password through the configured environment variable—never the INI file.

5. Retain the default cooldown or adjust it to match the incident-response workflow.

Run these commands from the extracted package directory after reviewing every file:

sudo install -m 0755 php2shell_monitor.py /usr/local/sbin/php2shell_monitor.py

sudo install -m 0640 php2shell-monitor.ini /etc/php2shell-monitor.ini

sudo install -d -m 0700 /var/lib/php2shell-monitor

sudo install -m 0644 php2shell-monitor.service php2shell-monitor.timer /etc/systemd/system/

sudo systemctl enable --now php2shell-monitor.timer

sudo systemctl list-timers php2shell-monitor.timer

sudo journalctl -u php2shell-monitor.service

The service permits writes only to `/var/lib/php2shell-monitor`. If authenticated SMTP is required, create a root-owned `0600` environment file containing `PHP2SHELL_SMTP_PASSWORD=...` and uncomment the `EnvironmentFile` line in the service. Prefer a local trusted mail relay where practical.

After installing the script and configuration, adapt the entry in `cron.example` under `/etc/cron.d/`. Cron and the systemd timer are alternatives; do not enable both. The one-minute schedule still cannot reliably capture short-lived child processes.

Do not delete suspicious files or kill processes before preserving evidence. Follow the incident-response process: isolate the affected host or pool where feasible, capture volatile process and network information, retain reverse-proxy/web/PHP/authentication logs, compare files with trusted builds, determine possible credential exposure, rotate affected secrets from a known-clean system and rebuild from trusted media when compromise is confirmed. Patching stops future exploitation of these CVEs but does not remove an existing compromise.

Extracted Entities