On 21 October 2026, the PHP project fixed a PHP security vulnerability rated critical. The two bugs, collectively called PHP2Shell, let an attacker run code on a web server without logging in. The problem is not limited to a single plugin or framework. It sits in the PHP runtime itself, which powers WordPress, Laravel, online shops and countless custom projects.
This article explains what happened, which follow-up problems it created, and how to secure your servers. Every statement comes from the original sources linked at the end. Where sources disagree or something is still unclear, we say so.
What happened? The PHP2Shell security vulnerability at a glance
On 21 October 2026, the PHP team released versions 8.5.12, 8.4.27, 8.3.36 and 8.2.35. They close two critical weaknesses that allow unauthenticated remote code execution (RCE). The team had announced the release on 20 October, describing two critical vulnerabilities, each rated CVSS v4.0 9.2.
- CVE-2026-109618: memory corruption when PHP runs out of memory (RCE via OOM corruption)
- CVE-2026-109619: use of stale global state after memory has been freed (RCE via stale global state)
According to the PHP project, every PHP installation that serves web requests is affected. That includes PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. The project considers mod_php the highest risk, because an attack there can succeed before any application code runs.
CVE-2026-109618: memory errors when memory runs out
When PHP cannot get enough memory while handling a request, it aborts the processing. Internal request data may then be only partly initialised. The cleanup that follows treats this invalid data as valid.
The Unit 42 analysis by Palo Alto Networks describes the mechanism this way: error handling through longjmp() leaves the request memory uninitialised, which lets an attacker reliably reach RCE by triggering memory exhaustion. According to the PHP project, the requests that do this can be multipart forms or file uploads. They can exhaust memory even when their size is within the configured limits.
CVE-2026-109619: stale state between requests
PHP can reuse one worker process for several requests in a row. If a request ends with a fatal error or a timeout, the internal state may not be fully cleaned up. A later request handled by the same worker can then access memory that has already been freed.
The PHP project confirms attack paths through the session upload progress feature and through the fatal error backtraces of PHP 8.5. Some paths affect mod_php, others PHP-FPM. Upload progress is enabled by default and can act as an early consumer of the stale state.
Why the PHP security vulnerability set off a chain reaction
A critical flaw in the core of a language is rarely an isolated event. PHP2Shell brought several knock-on problems at once. Each one raises the risk if you do not act quickly.
Public proofs of concept and exploit attempts
The situation is contradictory, and that is what makes it dangerous. On 22 October, Rapid7 reported that several public proof-of-concept exploits exist. Each one, however, only works for a specific combination of operating system, PHP version and web server. Rapid7 has not observed exploitation in the wild, but it has seen several reports of exploitation attempts, and it warns that a more portable technique could appear at any time.
The New Zealand National Cyber Security Centre (NCSC), on the other hand, says it is aware of reports of active exploitation. The picture is therefore not fully settled. The conclusion all sources share is the same: patch without delay.
Different patch states across distributions
Linux distributions and long-term support vendors received the fixes in advance, and some ship them as backports under older version numbers. A version number alone does not always tell you whether a system is protected. A Debian or Ubuntu package with an older version string can contain the fix, while a self-compiled PHP 8.2.34 does not.
The PHP project also warns that the volunteer repository rpms.remirepo.net had no updates on the day of release. Anyone relying on it should switch to distribution packages or build from source so they can apply updates immediately.
Red Hat Enterprise Linux 6 and 7 show a further problem. According to an oss-sec post on 22 October, Red Hat still lists the PHP packages as “under investigation” for CVE-2026-109618. An unofficial backport for PHP 5.4 and 5.3 has been published there. It is not confirmed by the vendor and should not go into production untested.
Old PHP branches with no future
PHP 8.1 and older versions no longer receive regular updates from the PHP project. For 7.4, 8.0 and 8.1 the team has provided minimal backports, mainly for users who compile PHP themselves. According to the PHP project, PHP 8.2 reaches end of life on 31 December 2026 and will receive no security fixes after that date.
Amazon Web Services reflects this in its security bulletin: for end-of-life runtimes 5.4 to 8.1 there is no planned fix, and migration to a supported branch is required.
A large attack surface on the internet
Palo Alto Networks reports that its Cortex Xpanse telemetry identified more than 22.6 million exposed instances that could be vulnerable to CVE-2026-109618 or CVE-2026-109619. This is an estimate based on telemetry, not a census, but it shows the scale: PHP runs on a large part of the web.
Why WAFs and security plugins are not enough
The flaws sit in the interpreter, before application code runs. A WordPress security plugin or an application-level firewall only starts after the vulnerable code has already executed. Several security vendors make this point. Updating your CMS or framework does not close the hole. Only an updated PHP does.
Background: other PHP vulnerabilities in 2026
PHP2Shell is not the only security issue this year. If you check a server today, look at the older CVEs too, because many of them affect the same version branches.
- CVE-2026-6735 (10 May 2026): XSS through the PHP-FPM status page. Affected: PHP 8.2 before 8.2.31, 8.3 before 8.3.31, 8.4 before 8.4.21 and 8.5 before 8.5.6. The status page is not meant for the public internet.
- CVE-2026-7261 (10 May 2026): use-after-free in SoapServer when session persistence is used and a SOAP request fails. Risk: memory corruption, information disclosure or a crash.
- CVE-2026-14355 (July 2026): buffer overflow in the AES-WRAP-PAD implementation of the OpenSSL extension. Applications using this algorithm can corrupt heap metadata.
- CVE-2026-17543 (30 July 2026): SQL injection in ext-pgsql caused by improper escaping of backslashes. The CVE record rates it CVSS 4.0 8.1 (high). Affected: 8.2 before 8.2.33, 8.3 before 8.3.33, 8.4 before 8.4.24 and 8.5 before 8.5.9.
- CVE-2026-17544 (30 July 2026): out-of-bounds write in
bccomp()through crafted input. Affected: 8.4 before 8.4.24 and 8.5 before 8.5.9.
The pattern is clear: PHP vulnerabilities arrived in several waves in 2026. If you update only once a year, you are almost certainly exposed.
Knock-on effects in the ecosystem: frameworks and libraries
Beside the interpreter, libraries that PHP applications use directly have their own flaws. An example from January 2026 shows how deserialisation gives attackers RCE: up to version 1.6.3, Laravel Reverb passes data from its Redis channel directly to unserialize() without restricting which classes can be created. The NVD rates it 9.8 (critical). The advisory suggests a strong Redis password, access only from a private network or loopback, or setting REVERB_SCALING_ENABLED=false if only one Reverb node runs.
The lesson is simple: your own code can be secure and a dependency or the interpreter can still open a door. PHP version, dependencies and server configuration must therefore be checked together.
How to increase security: step by step
The steps below follow the recommendations of the PHP project, Rapid7 and the SOC advisory from Prime Infoserv. They are listed in the order you should work through them.
Step 1: check your PHP version and package source
Run php -v on the server and compare the version with the table below. Also check whether the PHP package comes from your distribution, because then the package version with its backport notice is what counts.
| PHP branch | Minimum version with fix | Status |
|---|---|---|
| 8.5 | 8.5.12 | Fixed on 21 October 2026 |
| 8.4 | 8.4.27 | Fixed on 21 October 2026 |
| 8.3 | 8.3.36 | Fixed on 21 October 2026 |
| 8.2 | 8.2.35 | Fixed, end of life 31 December 2026 |
| 8.1 and older | No regular release | Vendor fix or migration required |
Step 2: patch and restart all workers
An update only takes effect once the running processes have restarted. Running workers keep the old binary until they restart, so a package upgrade alone does not protect you. A discussion on the PHP source repository about the PHP 7.4 backport describes exactly this: running workers keep using the old binary until PHP-FPM is reloaded or restarted.
Restart the PHP service in a targeted way (for example systemctl restart php8.3-fpm; the service name depends on your distribution). Then check php -v and the service status. If you run several PHP versions in parallel, restart each one separately.
Step 3: interim measures if you cannot patch right away
If you cannot update immediately, these measures reduce the attack surface. They do not replace the patch. The PHP project recommends the following:
- Remove the memory limit: set
memory_limit=-1, preferably withphp_admin_valuein the FPM pool or in the Apache configuration, so applications cannot override it. Restart all workers afterwards. - Limit upload size: without file uploads set
post_max_size = 8M, with uploadspost_max_size = 32M.upload_max_filesizemust be smaller thanpost_max_size. - Turn off upload progress: set
session.upload_progress.enabled=0inphp.inior the FPM pool, then restart all workers. Setting it withini_set()or.user.iniis too late. - Turn off fatal error backtraces (PHP 8.5 only): set
fatal_error_backtraces=0and restart the workers. - Limit input at the proxy: set maximum request size, number of input fields, multipart parts and nesting depth at the web server or reverse proxy, including requests without a Content-Length header.
Caution: removing the memory limit makes the server more sensitive to memory leaks. Set container or cgroup limits so that only the affected worker is killed. According to the PHP project, RLIMIT_AS or RLIMIT_DATA must not be used as a substitute, because they can trigger the vulnerable error path.
Step 4: restrict access where you can
Internal admin areas and status pages do not belong on the open internet. Put them behind a VPN or an IP allowlist. A public website cannot be shielded this way, which is why patching is the most important step there.
Step 5: check your logs, including past activity
Several sources report that exploitation attempts were seen before the patch existed. One DEV Community article recommends checking logs back to 17 October. That is a second-hand recommendation, not an official one. The SOC advisory from Prime Infoserv makes the key point: the absence of alerts does not prove that nothing happened. Look specifically for unusual requests with very large multipart bodies, unexpected fatal errors and sudden worker crashes.
If you find traces, treat the server as compromised. Reset credentials, check cron jobs, new files and outgoing connections.
Step 6: clarify with your hosting provider and package sources
If you use a hosting provider, ask in writing which package version contains the fix for CVE-2026-109618 and CVE-2026-109619. Do not rely on a general statement that “everything is patched”. The same applies to older branches: only a provider that names both CVEs explicitly can confirm the status.
A useful question to send your host is: “Which PHP version runs on my server, does it include the fix for CVE-2026-109618 and CVE-2026-109619, and were the PHP workers restarted afterwards?” The third question is often forgotten and is decisive. On shared hosting, also check whether the provider restarts the workers or whether you must do it from your control panel.
Step 7: long-term hardening
PHP2Shell shows why patching once is not enough:
- Use supported versions: plan the move before a version expires. The official overview is on php.net under “Supported Versions”.
- Enable automatic security updates: for the operating system and the PHP package, where your setup allows it.
- Apply least privilege: the web server user should only have write access to the directories it really needs. A compromised worker with few rights does less damage.
- Keep dependencies current: check Composer packages regularly for known vulnerabilities, for example with
composer audit. - Block dangerous functions: in
disable_functions, block only what you truly do not need. Test thoroughly afterwards, because an overly strict block breaks applications. - Hide error output in production: detailed error messages help attackers. Log errors internally instead.
- Keep secrets out of code: API keys and passwords belong in environment variables or a secrets manager.
Checklist: check your PHP security vulnerability in 10 minutes
- Version:
php -vshows 8.5.12, 8.4.27, 8.3.36, 8.2.35 or newer. - Package source: does the PHP package come from your distribution or host, and is the fix confirmed there?
- Workers restarted: no old PHP processes are running after the update.
- Upload progress off: if you cannot patch immediately, the setting is in place and active.
- Reachability: admin areas and status pages are not publicly reachable.
- Logs: unusual requests and worker crashes since 17 October have been reviewed.
- Dependencies:
composer auditshows no critical findings. - End of life: you know until when your PHP version is supported.
- Backups: a current, tested backup exists outside the server.
- Owner: one named person monitors updates.
FAQ: PHP security vulnerability PHP2Shell
Am I affected if my site only has static pages?
It depends on whether PHP handles web requests on the server at all. If PHP runs and processes requests, it is vulnerable, whether or not your site offers uploads.
Does updating my CMS, for example WordPress, help?
No. The flaws are in the PHP interpreter. You must update the PHP version.
Is a configuration change enough instead of an update?
No. The PHP project states explicitly that interim measures do not make an installation safe. An update is the only complete fix.
I run PHP 8.1. What now?
PHP 8.1 no longer receives regular updates. Use a vendor fix with confirmed coverage, or migrate to a supported branch.
Is my site compromised if I see nothing unusual?
Not necessarily, but you cannot rule it out. Missing alerts are not proof of safety, which is why the log review matters.
Conclusion
The PHP security vulnerability PHP2Shell is one of the most serious reports of the year. It affects the runtime itself, needs no login, and has set off a chain of knock-on problems: an unclear exploit situation, inconsistent backports, end-of-life branches and a large attack surface on the internet. The solution is clear, but it requires action: bring PHP to a patched version, restart the workers, review the logs and restrict access.
If your website runs on a builder or platform, ask your provider which PHP version is in use and how quickly security updates are applied. If you run your own servers, the responsibility sits with you.
Sources
- PHP.net: Security advisory – Critical remote code execution vulnerabilities (21 Oct 2026)
- PHP.net: News Archive 2026
- PHP mailing list: Upcoming Critical PHP Security Release (20 Oct 2026)
- CVE-2026-17543 (CVE.org) and CVE-2026-17544 (CVE.org)
- CVE-2026-7261 (CVE.org)
- CVE-2026-14355 (NIST NVD) and CVE-2026-6735 (NIST NVD)
- Rapid7: CVE-2026-109618 and CVE-2026-109619 – Critical Unauthenticated RCE in PHP
- Palo Alto Networks Unit 42: Threat Brief on CVE-2026-109618 and CVE-2026-109619
- NCSC New Zealand: Alert on CVE-2026-109618 and CVE-2026-109619
- AWS Security Bulletin 2026-143-AWS
- php-src issue #24527: backport for PHP 7.4
- oss-sec: unofficial backport for PHP 5.4 and 5.3
- PHP: Supported Versions
Keep reading: Lovable Alternatives · Best Free AI Website Builder · AI Agent Harness: Full Control