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 = 1in 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 = 0as 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.