PHP2Shell: why patching is only half the job
PHP2Shell: why patching is only half the job
Two critical PHP flaws, one uncomfortable lessonThe PHP project has shipped emergency releases to close two critical vulnerabilities, tracked as CVE-2...
Two critical PHP flaws, one uncomfortable lesson
The PHP project has shipped emergency releases to close two critical vulnerabilities, tracked as CVE-2026-109618 and CVE-2026-109619 and grouped under the nickname PHP2Shell. Both score 9.2 on the CVSS v4.0 scale and allow remote code execution without authentication. Exploitation attempts have already been observed in the wild, and attackers are actively tuning payloads to slip past web application firewall rules. If you run PHP anywhere in your stack, this is not a "schedule it for next sprint" kind of update.

The detail that unsettles most system administrators is that exposure has little to do with the application itself. You do not need a complex CMS, a forgotten plugin or an exotic endpoint. If the server runs an affected branch of the runtime, even a trivial static page can become an attack surface. The risk concentrates on how PHP is deployed rather than on what it serves, and Apache with mod_php stands out as the most exposed configuration, where a vector has been demonstrated that triggers before application code is ever reached.
What the two CVEs actually do
They are different bugs with a shared outcome, so treating them as a single patch note is a mistake:
- CVE-2026-109618 describes a chain of failures that ends in memory exhaustion and corruption, potentially leading to code execution with the permissions of the web process.
- CVE-2026-109619 involves stale global state with use-after-free consequences, which can leak memory contents and, in certain scenarios, execute code with worker privileges.
The memory disclosure angle deserves attention on its own. Anything the process holds in RAM — database passwords, API tokens, session data, even certificate material — could end up in the wrong hands depending on concurrent requests and server behaviour. In a shared hosting environment in Barcelona or Lleida, where dozens of clients share a runtime, that is a cross-tenant problem, not a single-site incident.
Patch, then actually restart
The fixed versions are PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. Installing the package is the easy part; the step people skip is the one that matters. Restart Apache, PHP-FPM and every persistent worker so the new runtime is genuinely loaded in memory. A patched package on disk with an old process still serving traffic protects nobody.
If you rely on a Linux distribution or an extended-support vendor, read the changelog carefully. Some maintainers backport fixes without an obvious version bump, so the number alone will not tell you whether you are covered. Verify against the advisory, not against your assumptions.
Be aware too that the fix changes behaviour: it introduces a hard memory limit, and hitting it can terminate processes while bypassing shutdown handlers. Expect some noise after deployment and plan a monitoring window around it.
Containment while you prepare the update
Where an immediate upgrade is impossible, temporary mitigations reduce the blast radius without closing the hole:
- Force memory_limit to -1 in a way the application cannot override, keep post_max_size low and cap request size at the web server or reverse proxy.
- Avoid RLIMIT_AS or RLIMIT_DATA as substitutes for memory limits, as they can activate vulnerable code paths.
- Disable session.upload_progress.enabled and restart all workers to reduce exposure to the use-after-free flaw.
- On PHP 8.5, disabling fatal_error_backtraces offers partial containment, again followed by a full worker restart.
Treat these as tourniquets, not cures. And remember that PHP 8.1 and earlier no longer receive upstream updates at all, so staying on an unsupported branch is now a security decision rather than a maintenance preference.
Signals that someone is knocking
After patching, watch for behaviour consistent with exploitation attempts: anomalous multipart requests immediately followed by memory-limit errors, sudden waves of HTTP 500 responses, unusually large PHPSESSID cookies, or workers restarting for no clear reason. Individually these are noise; clustered together they tell a story.
This is where per-server firewalling stops being enough. A single machine learning from its own logs will block an address today and forget it tomorrow, while the same attacker moves to your second node in Tarragona or Girona. Abuse Shield from ALMC addresses exactly that gap: it centralises protection across your fleet, manages fail2ban on multiple machines from one place, blocks malicious IPs automatically and shares an IP reputation feed between every server you run. When one node identifies a hostile source, the rest already know about it.
For hosting companies and SMEs running their own infrastructure, that shared intelligence turns isolated incidents into collective defence. Combined with prompt patching, disciplined restarts and GDPR-conscious log handling, it gives you something the advisory alone cannot: a perimeter that keeps learning after the update window closes.
Related
- How to Harden Your Servers with Fail2ban and IP Reputation Feeds
- Fail2ban: Your First Line of Defense Against Unauthorized Server Access
- Critical libssh2 flaw: urgent patch for SSH servers
- Desarrollo web
Put these ideas into practice
Talk to ALMC about a solution for your business. Explore your options or contact our team.
