How to block PHP2Shell before your host patches PHP
Updating PHP is the only complete fix for PHP2Shell. If your host hasn't patched yet, these documented stopgaps buy time: session.upload_progress off, a memory_limit tweak, FPM limits and WAF rules — with their caveats.
By the Presscomet teamPublished 12 min read
On this page
First, the thing nobody can sell you around
If you’re here, your WordPress site is probably running on a PHP version that still has the PHP2Shell flaws (CVE-2026-109618 and CVE-2026-109619), and your host hasn’t shipped a patched build yet. You want to do something this hour. This page is that something — but it opens with the sentence the PHP security team put at the top of their own advisory, because every mitigation below is a footnote to it:
Updating PHP is the only complete fix
mod_php — may run before any of your defences do. Use these to buy hours while a patched PHP lands, not as a destination.With that said, buying hours is worth a lot right now. Scanning started before the patches existed: Amazon’s threat-intelligence team logged an exploitation attempt on 17 October, four days before the fix, and Cloudflare reported attempts climbing from thousands to millions once disclosure happened. As of 24 October no successful compromise had been publicly confirmed, and PHP2Shell was still not in CISA’s Known Exploited Vulnerabilities catalog — but treat your site as actively targeted, because it is.
- CVE IDs
- CVE-2026-109618 · CVE-2026-109619
- Severity
- Critical · CVSS v4.0 9.2
- Complete fix
- Patched PHP only
- Stopgaps buy
- Hours, not safety
- Highest-risk SAPI
- Apache mod_php
- CISA KEV
- Not listed (as of 24 Oct)
Every setting here is a legitimate hardening change — a switch turned off, a limit adjusted, a firewall rule enabled. There is no exploit code on this page and you don’t need any to defend yourself. If you want the full picture of what PHP2Shell is and how to patch it properly, read the main PHP2Shell and WordPress guide first; this is the “my host hasn’t patched and I can’t wait” companion to it.
Triage in five minutes
Before you change a single setting, answer three questions. They decide which stopgaps are even available to you, and whether the honest answer is “harden it” or “take it down”.
Step 1: Which PHP version and SAPI is it?
Check Tools › Site Health › Info › Server for the PHP version and PHP SAPI.apache2handlermeans mod_php (highest risk),fpm-fcgimeans PHP-FPM,litespeedmeans LiteSpeed. A site on 8.1 or older with no vendor backport is in the most dangerous group.Step 2: Can the origin be reached without your CDN?
If attackers can hit the server’s IP directly, a WAF in front of it does nothing. You’ll need to lock the origin to your CDN’s IP ranges (or a firewall) for the WAF rules below to count.Step 3: Who can actually change PHP config here?
On managed hosting you can’t editphp.ini— you ask the host, and your job is to chase them for a patch date. On a VPS or your own server you can apply everything below yourself. Knowing which you are saves an hour of trying the wrong thing.
Can't tell if your host has patched?
PHP settings that close specific paths
These are the interim mitigations the PHP project and major vendors documented. They must go in php.ini, the PHP-FPM pool configuration, or your web server’s config — not in a per-directory .user.ini and not via ini_set() in a plugin, because the dangerous path can run before your code does. After any change, restart all PHP workers or the change does nothing. Pick the tab that matches where you set PHP config.
The simplest place if you have one php.ini for the site. Find the active file in Site Health (“Loaded Configuration File”) or with php --ini, edit it, and restart PHP.
; Closes the session upload-progress trigger (used by several demonstrated paths)session.upload_progress.enabled = 0; Blocks the out-of-memory trigger behind CVE-2026-109618.; This removes the memory cap — restore a finite value the moment PHP is patched.memory_limit = -1; PHP 8.5 ONLY: disables the fatal-error backtrace path. Harmless to omit on 8.2–8.4.fatal_error_backtraces = 0; Shrink the attack surface for oversized multipart bodiespost_max_size = 8MBecause memory_limit = -1 lets a single request use unbounded RAM, pair it with the smaller post_max_size above and a request-size limit at your proxy or web server, so you don’t simply trade a code-execution risk for an out-of-memory crash.
On PHP-FPM, set these in the pool file (for example /etc/php/8.3/fpm/pool.d/www.conf) with php_admin_value/php_admin_flag, which cannot be overridden by .user.ini or ini_set(). That’s exactly what you want for a security setting.
php_admin_flag[session.upload_progress.enabled] = off; Restore a finite memory_limit after PHP is patchedphp_admin_value[memory_limit] = -1; PHP 8.5 pools onlyphp_admin_flag[fatal_error_backtraces] = offphp_admin_value[post_max_size] = 8M; Recycle each worker after one request if you can spare the performance (Qualys)pm.max_requests = 1# Validate the FPM config first$ sudo php-fpm8.3 -t# Restart so the new pool settings load$ sudo systemctl restart php8.3-fpmpm.max_requests = 1 makes each worker handle a single request and then exit, which disrupts the cross-request reuse behind CVE-2026-109619. It costs real performance, so only use it on a site that can absorb that until the patch lands.
If PHP runs as an Apache module (mod_php), set the values in the vhost or an .htaccess you control, using the admin directives so nothing can re-enable them:
php_admin_flag session.upload_progress.enabled Off# Restore a finite memory_limit after patchingphp_admin_value memory_limit -1# Also cap the request body at the web server so oversized multipart posts are refusedLimitRequestBody 8388608Read the mod_php caveat below before you rely on this: on mod_php the most dangerous path can fire before these are even consulted, so server-config hardening buys less here than it does on FPM. LiteSpeed users set the same PHP directives in the LSAPI/php configuration and then perform a graceful restart.
One mitigation you almost certainly can't use on WordPress
file_uploads = Off plus rejecting multipart/form-data at the web server. That genuinely helps apps that never accept uploads — but WordPress needs uploads for the media library, so turning them off breaks the editor for most sites. It’s listed for completeness; skip it unless you truly don’t use the media library.WAF and CDN rules: useful, not a cure
A content delivery network or web application firewall in front of your origin can filter a large share of the automated PHP2Shell traffic. Cloudflare said it deployed managed rules and watched attempts rise into the millions after disclosure; Imperva and other vendors shipped rules too. If you already route traffic through one, make sure the relevant managed ruleset is in block mode, not just “log”.
Three things decide whether a WAF actually helps here, and all three are easy to get wrong:
- The origin must be unreachable directly. If an attacker can connect to your server’s IP and skip the CDN, the rules never see the request. Lock the origin firewall to your CDN’s published IP ranges.
- It filters patterns, not the bug. A WAF matches traffic that looks like the known attempts — for example multipart requests that abuse the upload-progress field. Defenders tune these conceptually around that behaviour; we deliberately don’t publish rule payloads, because a precise rule is one edit away from a bypass map. Trust your vendor’s managed ruleset over a hand-rolled regex.
- In-process firewalls are weaker here. A security plugin or RASP agent runs inside PHP, after the request has been parsed. The most dangerous path can trigger before that point, so a plugin firewall is the least reliable layer for this particular flaw. It’s still worth having; just don’t count on it.
A reasonable belt-and-braces setup for a few hours
When the honest answer is “take it offline”
Some sites can’t be patched quickly and can’t be meaningfully hardened. The clearest case is a site on PHP 8.1 or older with no vendor backport: there is no supported fixed release on those branches, and the only real options are a patched build from your host/distro or an upgrade. For those, the guidance from security agencies is unambiguous.
CISA
Take unpatchable systems offline
Organisations that can't update immediately, or still run PHP 8.1 or older, were advised to take PHP-based systems offline until they can be patched or upgraded.NSA
Go offline if you can't update
The NSA recommended taking affected systems offline where updating isn't possible, rather than leaving an exposed runtime on the internet.Sophos
Restrict access at the network
Where a full takedown isn't practical, put the site behind network-level authentication or an allowlist — not a maintenance-mode plugin, which runs inside PHP and can be bypassed by the pre-application attack path.
“Offline” here means the PHP application stops answering untrusted requests from the internet: a holding page served by the web server itself, a firewall rule that only allows your own IP, or HTTP auth enforced by the server (not WordPress). A WordPress maintenance-mode plugin does not count, because the attack can run before WordPress loads. Snapshot the site first so you can bring it back cleanly once PHP is patched.
Why Apache mod_php is the awkward case
It’s worth being precise about why some of this advice comes with an asterisk. The PHP project rates Apache mod_php as the highest-risk setup because a demonstrated exploit triggers CVE-2026-109618 from an unauthenticated request before any application code runs. PHP-FPM’s startup behaviour blocks one of the out-of-memory paths, though the stale-state issue (CVE-2026-109619) was still validated under suitable application conditions.
The practical consequences for mitigation:
- Plugin firewalls and RASP can’t reliably save a mod_php site, because they live inside the request they’re trying to protect, and the trigger can precede them.
- The PHP-level settings still apply — turning off upload progress and removing the memory cap close the triggers at the engine level, which is upstream of your application — so they’re the most valuable layer on mod_php. But they’re a tourniquet, not surgery.
- If a mod_php site can’t be patched within hours, lean toward taking it offline rather than trusting layered in-process defences. Moving from mod_php to PHP-FPM is itself a hardening step worth planning once the fire is out.
When the patch lands — undo the stopgaps
The moment your host confirms a patched PHP (or you’ve installed one yourself and restarted the workers), these mitigations have done their job and some of them should be reversed, because they carry their own costs:
Step 1: Restore a finite memory_limit
Putmemory_limitback to a sane value such as256M. Leaving it at-1long-term invites out-of-memory crashes and noisy-neighbour problems.Step 2: Relax pm.max_requests
If you set FPM’spm.max_requests = 1, return it to its normal value (often500–1000); one-request-per-worker is a heavy performance tax.Step 3: Decide about upload progress
You can leavesession.upload_progress.enabled = 0off indefinitely — most sites never use it — or re-enable it if something depends on it.Step 4: Confirm the version actually changed
Reload Tools › Site Health › Info › Server and verify the new version. If it still shows the old one, the workers didn’t restart — see our guide to PHP still showing as vulnerable after an update.Step 5: Keep the firewall rules
The WAF/CDN managed ruleset and a locked-down origin are good hygiene to keep running long after this specific incident.
Then go back to the full workflow: confirm the patch, check whether you were exposed during the window, and work through the “was I hacked?” checklist. Patching closes the door; it doesn’t evict anyone who got in while it was open.
The longer-term fix: fewer emergencies like this one
PHP2Shell won’t be the last runtime bug, and “harden it for a few hours and hope the host patches” is a stressful way to run a website. There’s a more structural answer for content sites: stop putting a PHP interpreter in the path of every public request.
Where Presscomet fits — honestly
Presscomet runs the WordPress admin, block editor, URLs and REST API on Node.js with a single SQLite file and no PHP runtime. With no PHP there, the entire PHP-runtime class of bugs — PHP2Shell included — simply doesn’t apply, and there’s no php.ini to scramble to edit at 2am. It is not “unhackable”: Node.js, its npm dependencies, Presscomet’s own login and the server underneath all still need patching, and they’ll have their own advisories one day. It also doesn’t run PHP plugins (the common ones are built in) and doesn’t support WooCommerce stores.
If running a PHP-free stack appeals once this is over, check your site against a migration — it only reads your public site and never changes anything on your server — or read our WordPress security guide and how to check and update your PHP version for the patch-first path. Either way: patch first, undo the stopgaps, then decide calmly.
Sources
Facts checked against these sources on October 24, 2026. Things change quickly; the vendor advisory always wins.
- [1]PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 security releases (with interim mitigations) — PHP.net
- [2]PHP2Shell advisory: detection and interim mitigations — Sophos
- [3]Two critical PHP flaws: find, mitigate and patch PHP2Shell — Qualys
- [4]PHP2Shell: the session upload-progress trigger — Imperva
- [5]PHP2Shell FAQ — watchTowr
- [6]PHP2Shell exploitation started days before patches — SecurityWeek
- [7]CVE-2026-109618 / CVE-2026-109619 analysis and CISA offline guidance — Horizon3.ai
- [8]AL26-026 Critical vulnerabilities impacting PHP — Canadian Centre for Cyber Security
- [9]Known Exploited Vulnerabilities catalog — CISA
Frequently asked questions
Can I block PHP2Shell without updating PHP?
Not completely. The PHP project is explicit that updating PHP is the only complete fix. You can close specific attack paths with documented settings (turning off session.upload_progress, setting memory_limit administratively, and on PHP 8.5 disabling fatal_error_backtraces) and filter traffic with a WAF, but these are stopgaps to buy hours, not a replacement for a patched PHP build.
Does disabling session.upload_progress stop PHP2Shell?
It closes several of the demonstrated attack paths, because the session upload-progress feature runs during multipart parsing before your application code executes and was used as a remote trigger. Set session.upload_progress.enabled = 0 in php.ini, the PHP-FPM pool or the server config — not in .user.ini or ini_set() — and restart all PHP workers. It does not cover every path, so treat it as a temporary measure.
Is setting memory_limit to -1 safe as a mitigation?
It is a deliberate, temporary trade-off. Removing the memory limit blocks the out-of-memory trigger behind CVE-2026-109618, but it also lets a single request consume far more RAM, so pair it with a tighter post_max_size and request-size limits at your proxy, set it administratively with php_admin_value so applications can't override it, and restore a finite limit as soon as PHP is patched. Don't substitute RLIMIT_AS or RLIMIT_DATA for it.
Will a Cloudflare WAF rule protect me from PHP2Shell?
It helps and it is worth enabling, but it is not a fix. Cloudflare and other vendors deployed managed rules for PHP2Shell traffic, which filter a large share of the automated attempts. They only help if your origin server can't be reached directly (bypassing the CDN) and if the rules actually match the traffic. Keep patching as the goal.
Do these mitigations work on Apache mod_php?
Partly, and this is the most important caveat. The riskiest demonstrated attack triggers CVE-2026-109618 on mod_php from an unauthenticated request before any application code runs, so in-process protections such as security plugins or application firewalls can't reliably stop it. The PHP-level settings still apply, but if you can't patch a mod_php site quickly, taking it offline is the safer call.
Should I take my WordPress site offline over PHP2Shell?
If it runs PHP 8.1 or older and can't be patched or upgraded, yes — that is the guidance from CISA and others, and the NSA recommended going offline where you can't update. For a site on a supported branch (8.2–8.5) the better move is to patch within hours and apply the stopgaps in the meantime, rather than take it down.
Presscomet keeps your wp-admin, editor, URLs and content, and serves pages without PHP or MySQL. Check your site for free, then migrate in one click — your old site is only ever read.
Keep reading
- SecurityPHP2Shell and WordPress: are you affected, and how do you fix it?
Two critical bugs in PHP itself put almost every WordPress site on an affected runtime until the host patches it. Here’s what happened in plain English, a checker that tells you whether you’re affected, and step-by-step fixes for every kind of hosting.
- HostingIs your WordPress host patched for PHP2Shell? What to ask (with an email template)
On most WordPress sites you can’t patch PHP yourself — your host has to. Here’s who is responsible on each kind of hosting, the four questions that get you a real answer, and a ready-to-send email.
- SecurityHow to check and update your PHP version in WordPress (2026)
Your PHP version decides whether your WordPress site still gets security fixes. Here’s how to find it in under a minute, what’s still supported, and a safe way to upgrade without breaking anything.