Threat Intelligence

PHP2Shell: Two critical flaws in PHP, and no password needed

Jacob Dobson
Placeholder for Jacob DobsonJacob Dobson

Jacob Dobson , Director of Cyber Defence , Nomios UK&I

8 min. read
Placeholder for PHP2 Shell Two critical flaws in PHP and no password neededPHP2 Shell Two critical flaws in PHP and no password needed

Share

Last updated: 22 Oct 2026

This is not a flaw in your application. It is a flaw in PHP itself.

On 21 October 2026, the PHP security team released emergency fixes for two critical vulnerabilities, CVE-2026-109618 and CVE-2026-109619, now known as "PHP2Shell". The details leaked before the planned disclosure. Several vendors have reported attack activity, and proof-of-concept code is circulating.

Nomios SOC customers were notified at 10:00 on 21 October, ahead of the fixes being published, and detections are live across the Nomios group. The detail is in "What Nomios is doing" below.

The key points:

  • Two critical vulnerabilities
  • CVSS v4.0 score of 9.2 for each
  • No login required
  • Fixed in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35

PHP sits underneath WordPress, Drupal, Joomla, Magento, Nextcloud and phpMyAdmin, among many others. Researchers have shown working attacks against all of those, plus MediaWiki, Roundcube, Laravel, Symfony and WHMCS. It makes no difference how well the application on top is built.

The attack happens while PHP is still reading the incoming request, before your application code runs. Your login page and your MFA never get involved.

How it works

Both flaws are use-after-free bugs, and both start with a request ending badly, usually because PHP runs out of memory part-way through.

CVE-2026-109618 is the out-of-memory flaw. PHP gets interrupted while a request is only partly set up, and the cleanup that follows treats that half-built data as if it were valid.

CVE-2026-109619 is the stale state flaw. Data belonging to one request survives after its memory has been freed, and the next request handled by the same worker can end up using it. PHP has confirmed attack paths through session upload progress handling and, on PHP 8.5, through fatal error backtraces.

One technique has also been shown to push around 67 KB of server memory back to the attacker inside a PHPSESSID cookie header. That memory can hold whatever the worker was handling at the time, including passwords, session tokens and API keys.

What "exposed" actually means

It does not mean compromised. It means you are running a PHP version from before the fixed releases on a server that handles web requests. PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed are all in scope, and PHP rates mod_php as the highest risk because the attack can fire before any application code runs.

It also covers sites you do not run yourself. If a hosting provider or supplier runs PHP for you, you are exposed until they patch.

The exploitation reports are mixed:

  • Cloudflare reported attack traffic on the morning of 21 October, before the fixes were released
  • watchTowr reports exploitation in its honeypot network, and Hadrian reports exploitation at scale
  • Amazon recorded an attempt on 17 October, four days before disclosure, and says compromise may predate the advisory. It also says it is unclear whether those early attempts would have worked on real systems
  • Patchstack first reported exploitation incidents, then said its telemetry showed only probing and no hard evidence of breaches
  • CISA said it had not observed exploitation at the time of its alert, and neither CVE was in its Known Exploited Vulnerabilities catalogue as of 21 October
  • No indicators of compromise have been confirmed publicly

Public exploit code is circulating, but how well it works is disputed. Do not run it on your own systems to test yourself. Unverified exploit code is sometimes laced with malware, and patching is the better test.

Impact of PHP2Shell

An attacker who gets code running on your web server is inside your environment, with the same access as the PHP process. What happens next depends on what that process can reach.

Key risks include:

  • Remote code execution with no authentication
  • Theft of secrets held in memory
  • Defacement, malware and data theft from the affected site
  • Movement from the web server into the wider network
  • Outages from repeatedly crashing PHP processes

Where PHP holds database credentials, or sits close to file shares and internal systems, the risk increases significantly.

What Nomios is doing

10:00 on 21 October: every Nomios SOC customer notified. That was ahead of the fixes being published at 14:00 UTC.

Detections deployed across the Nomios group. There are no confirmed indicators of compromise to hunt for, and a signature for one public exploit would miss the next variant. So we are not chasing the exploit. We are watching for what an attacker has to do once they have code running on a PHP web server, because an attacker who wants to do anything useful with that access usually has to do some of it.

Active sweeping, live now. To date, across the Nomios group, we are not observing exploitation of PHP2Shell and are remaining on high alert.

The detections are built around these areas:

  • Web server and PHP processes behaving in ways a web application normally does not, such as starting command-line tools
  • Unexpected files appearing on the web server, including anything that looks like a web shell
  • Changes to web server configuration
  • Programs being run from places they have no reason to run from

If you have any questions or queries, contact your account manager or the Nomios SOC directly.

What to do now

Find everything that runs on PHP

Websites, shops, portals, intranets, webmail, file sharing, and anything a host or supplier manages. Include containers. Patching the host does nothing for PHP baked into an image, so those images need rebuilding and redeploying. You cannot patch what you do not know about.

Update PHP and restart every worker

Install PHP 8.5.12, 8.4.27, 8.3.36 or 8.2.35, or your vendor's fixed package. On Windows, fixed builds are on the PHP downloads page. Start with anything internet-facing, and with mod_php if you run it.

Two common mistakes. The fix only takes effect once workers restart, so restart PHP-FPM and Apache after the install, not just the package manager. And Linux distributions often backport fixes without changing the upstream version number. Check your vendor's security notice rather than relying on the version string alone.

# PHP-FPM (use your version in place of 8.3) systemctl restart php8.3-fpm # Apache with mod_php systemctl restart apache2        # Debian and Ubuntu systemctl restart httpd          # RHEL and derivatives

Check what the web server is actually running. php -v on the command line can report a different PHP from the one serving your site.

If you cannot patch today, reduce the exposure

Take it offline if you can. If a server cannot be patched today and you can afford the downtime, stop PHP and serve a static maintenance page from the web server until you have updated. The maintenance modes built into CMS and shop platforms do not help, because PHP processes the request before the application looks at them. If you cannot go offline, set the web server to reject everything except GET and HEAD requests. Visitors can still browse, but cannot log in or submit forms.

PHP publishes interim measures. They block specific attack paths and do not make a server safe. They buy you time, nothing more.

For the stale state flaw (CVE-2026-109619):

  • Set session.upload_progress.enabled=0 and restart every worker
  • On PHP 8.5, set fatal_error_backtraces=0 and restart every worker

For the out-of-memory flaw (CVE-2026-109618):

  • Set memory_limit=-1 in a way applications cannot override
  • Set post_max_size = 8M if you do not need uploads, or 32M if you do, and keep upload_max_filesize below it
  • Enforce limits at the web server or proxy for request size, field count, multipart parts, headers and nesting depth, including for requests with no usable Content-Length

For PHP-FPM, put the settings in the pool configuration so applications cannot undo them:

php_admin_flag[session.upload_progress.enabled] = off php_admin_value[memory_limit] = -1 php_admin_value[post_max_size] = 8M

Do not rely on ini_set() or .user.ini, because they apply too late. Then confirm the values from a request served by PHP-FPM, not from the command line.

A few cautions. memory_limit=-1 lets one request use all the server's memory, so watch usage and put the limit back after patching. Do not use RLIMIT_AS or RLIMIT_DATA as a substitute, as they can cause the very allocation failure the attack needs. A container or cgroup memory limit is a better safety net, ideally one that kills only the affected worker.

Sansec also suggests blocking multipart/form-data requests at the web server, as every known trigger uses one. It is a blunt last resort, because it breaks file uploads and some forms, so test it first.

# nginx, inside each server block that passes requests to PHP if ($http_content_type ~* "multipart/form-data") {    return 403; }

A web application firewall can help at the edge, and Cloudflare had rules live before the release. But the attack runs inside PHP before your application sees anything, so do not rely on edge rules in place of patching.

Ask your hosts and suppliers

Ask whether they have patched, and get the answer in writing. Do not accept "we are looking into it".

Check for signs of compromise, and look back

Amazon recorded an attempt on 17 October, so do not stop your review at 21 October. Start the look-back from there.

Look at what your web servers and PHP have been doing, not just whether they are patched. Unexpected programs being started by the web server, new or changed files on the server, new cron jobs or scheduled tasks, and new accounts are the usual signs that someone has got in. Repeated worker crashes, bursts of out-of-memory errors and abnormally large PHPSESSID cookie headers in responses are worth chasing too, although none of them is a published indicator on its own.

If you find something, isolate the server and keep the web server and PHP logs. If a server may have been exposed, rotate the credentials, API keys and session secrets it handles once it has been patched.

Additional recommendation

Check which PHP version you are actually running, and which of your systems are out of support.

PHP 8.1 and older no longer receive updates from the PHP project. Some distributions and LTS vendors provide backported fixes, so ask yours. For those building from source, the PHP security team published minimal backports for 7.4, 8.0 and 8.1. Use them to get out of trouble, not as a long-term plan. The real fix is moving to a supported version.

PHP 8.2 reaches end of life on 31 December 2026. If you are on it, patch now, and plan the upgrade before the year is out.

One more item from PHP's own guidance: fix any fatal errors and execution timeouts that an attacker can trigger, including in upload and import handling, because they sit on this attack path.

Full technical detail is in the official PHP security advisory on php.net.

Connect with us

Get in touch with our security experts

Our UK team is available for a quick call or video meeting. Let's connect and discuss your security challenges, dive into vendor comparison reports, or talk about your upcoming IT projects. We are here to help.

Placeholder for Portrait of engineer beard wearing poloPortrait of engineer beard wearing polo
Updates

More updates