Stopgap

PHP2Shell interim mitigations (if you can’t patch today)

Short answer

Patching is the only real fix. If you need a few hours or days, you can reduce exposure by disabling session.upload_progress, enforcing request-size limits at PHP and your web server, keeping WAF rules on, and restricting or isolating public access. Revert costly settings once you’ve patched.

On this page

These are stopgaps, not fixes. A PHP core developer put it plainly: “the only mitigation is patching/upgrading PHP.” Use the steps below to buy time, then patch.

1. Disable session upload progress

PHP’s session upload progress feature is part of one confirmed PHP2Shell attack path, and the PHP advisory recommends turning it off as an interim measure. Very few sites rely on it.

; In the php.ini used by your web runtime, e.g. /etc/php/8.3/fpm/php.ini
session.upload_progress.enabled = 0

Then restart PHP so the setting takes effect:

sudo systemctl restart php8.3-fpm    # or: apache2 / httpd for mod_php

Check it from the web runtime, not the CLI — the CLI reads a different ini file.

2. Enforce request-size limits

Keep request bodies small at both layers: PHP and the web server or proxy in front of it. Pick values that suit your largest legitimate upload.

; php.ini
post_max_size = 8M
upload_max_filesize = 8M
# Nginx — server or http block
client_max_body_size 8m;
# Apache — virtual host or directory
LimitRequestBody 8388608

Vendor guidance also recommends enforcing decoded request-size limits at the proxy or WAF where your platform supports it.

3. Turn on WAF protection

Cloudflare has deployed rules for known PHP2Shell attack vectors, available to all customers including the free plan — make sure the managed rules are enabled for your zone. If you use another WAF or CDN, check your vendor’s advisory for an equivalent rule set.

WAF rules only cover the vectors they know about, and Cloudflare has already seen attempts to evade its protections. Treat them as a seatbelt.

4. Optional hardening for specific setups

  • PHP-FPM: setting pm.max_requests = 1 in the pool configuration makes each worker exit after a single request. It limits state carrying over between requests (CVE-2026-109619) at a significant performance cost.
  • PHP 8.5: the advisory lists fatal_error_backtraces = 0 as an additional setting.
  • Containers: keep memory limits enforced with cgroups/container limits so a runaway worker can’t take the host down.

5. Restrict or isolate exposure

  • Put admin panels, staging sites and internal tools behind a VPN or IP allowlist.
  • Temporarily take offline anything public that isn’t essential — the UK’s NCSC urged exactly this for systems that can’t be fixed immediately.
  • If one server hosts many sites, prioritise patching the ones that face the internet with the most traffic and the most sensitive data.

What not to rely on

  • Hiding the PHP version (expose_php = Off) — attackers don’t need to see it.
  • Updating WordPress, Laravel or plugins — the bug is in PHP itself.
  • RLIMIT_AS / RLIMIT_DATA — explicitly called out as not a substitute for patching.

After you’ve patched

Patch, restart, verify, then revert performance-heavy stopgaps such as pm.max_requests = 1. You can keep session.upload_progress.enabled = 0 if you don’t use the feature. Finally, work through the compromise checklist.

Shayan Abbas writes these PHP security guides from the official advisories and vendor guidance listed below, and updates them when those change. About this site

Sources

  1. Qualys — PHP announces critical security release (interim mitigations)
  2. The Hacker News — PHP issues emergency patches (PHP core developer on mitigations)
  3. Help Net Security — Cloudflare WAF rules and NCSC guidance

Know about the next critical PHP bug first

Short, plain-English alerts when a serious PHP vulnerability or fix lands — with what to patch and how. About two emails a month.