PHP2Shell exposure,
seen from outside
Check whether your site publicly discloses a PHP version affected by CVE-2026-109618 or CVE-2026-109619. Passive, evidence-based and free: no account, no email, no exploit attempts.
- Affected
- PHP 5.4 to 8.5
- Exploitation
- Proven in research
- Attacker needs
- No login
- Fixed
- 21 Oct 2026
Enter a domain you own or are authorised to assess. No email needed.
One ordinary HTTP request, plus two to confirm a PHP front controller. No exploit attempts, no payloads, no admin paths. Detection is not guaranteed to be complete.
Am I affected by PHP2Shell?
If any internet-facing host you own runs PHP below 8.5.12, 8.4.27, 8.3.36 or 8.2.35, it is affected. PHP 5.4 through 8.5 carry at least one of the two flaws, and PHP 8.1 and older receive no upstream fixed release at all. Updating WordPress, Drupal or Joomla does not fix it, because the flaw is in the PHP runtime rather than in the application.
- What is PHP2Shell?
- Two critical flaws in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, published on 21 October 2026. Both are rated CVSS v4.0 9.2 by the PHP security team. One allows unauthenticated remote code execution, the other discloses process memory that can hold passwords, session tokens and API keys from other users' requests.
- Is it being exploited?
- Pre-authentication remote code execution has been demonstrated in research against default WordPress, Drupal and Joomla installations. As of 22 October 2026 there are no reports of exploitation in the wild, but the patch diffs and the technical analysis are both public.
- What do I do about it?
- Upgrade PHP to the fixed release for your branch, or to your vendor's patched package, then restart PHP-FPM, Apache and every PHP worker. Move PHP 8.1 and older to a supported branch or take it off the internet. Configuration changes reduce exposure but do not replace the upgrade.
- How do I tell whether a site is affected from outside?
- Check whether it discloses a PHP version in its
X-Powered-ByorServerheader and compare it with the fixed release for that branch. Most hosts hide the version, so an external check usually returns "not verified" rather than a clean result. The checker on this page does exactly that.
Three signals, and what each one proves
PHP is a backbone of the web. It powers WordPress, Joomla, Drupal, MediaWiki and roughly 70% of all websites. The flaw is in the runtime, not in any one application, so updating WordPress or its plugins does not fix it. This check reads only what your server already tells every visitor, and the result states which signal it relied on.
Disclosed PHP version
An X-Powered-By or Server header naming a PHP version is the
only signal that can decide patch status. When present, it is compared with the fixed
release for that branch.
PHP presence without a version
A PHPSESSID cookie or PHP-backed application markers show PHP is in use but
say nothing about the patch level. This returns an inconclusive result, never a clear one.
Nothing disclosed
Most hardened and CDN-fronted sites reveal nothing. That is flagged amber as "check it", never green: not seeing PHP is not the same as it being absent or patched.
PHP2Shell: two critical flaws, one update
Both were published on 21 October 2026 and both are fixed by the same set of releases. The PHP project states that updating is the only complete mitigation.
CVE-2026-109618
Remote code execution via out-of-memory early-exit corruption
PHP uses a non-local jump to abort a request when an allocation fails. If memory runs out while request state is only partly initialised, the early exit is not handled correctly and request shutdown can read or branch on invalid state. Reachable through multipart parsing, which makes it unauthenticated.
CVE-2026-109619
Remote code execution via stale global state use-after-free
PHP can leave global state (error, session, object or extension data) pointing at memory owned by a previous request. When a worker is reused and that memory has been freed, code running before normal request initialisation can use it. A crafted heap layout can turn this into remote code execution.
Four bugs, one weak spot
| Bug | What goes wrong | Shown against |
|---|---|---|
| Session upload-progress use-after-free | The session decoder holds request-owned state in a global. A fatal memory error frees the request heap but leaves that global set, and the next request on the same worker reuses it. | WordPress, Drupal and Joomla (chained) |
| Process-memory disclosure | Multipart upload parsing runs before modules start. An out-of-memory error leaves the session ID pointing at freed memory, and a later multipart request copies heap contents into the PHPSESSID cookie. It works even where the application never starts a session. | Any PHP application |
| Fatal-error backtrace use-after-free | The stored backtrace of a fatal error is never cleared, so diagnostics in the following request follow a dangling pointer. | Drupal |
| OPcache type confusion | A failed allocation leaves shared OPcache slots marked free while another worker is still using them, so one object is read as a different type. | WordPress |
All four share one pattern: a request is forced to fail with an out-of-memory or fatal error, PHP frees that request's memory but leaves a pointer to it in a global, and the next request on the same worker trusts the stale pointer. Long-lived workers such as PHP-FPM and Apache mod_php therefore carry damage from one request into the next. The PHP project assigns these to CVE-2026-109618 (out-of-memory corruption) and CVE-2026-109619 (stale state across requests); further untracked variants may exist, and the fix addresses the shared root cause.
Which PHP versions are affected
Ruleset 2026.10.22-6, last verified 2026-10-22 against the official php-src advisories. Platform PHP floors last verified 2026-10-22.
| PHP branch | Affected | Fixed in | Status |
|---|---|---|---|
8.5 |
< 8.5.12 |
8.5.12 |
Supported upstream |
8.4 |
< 8.4.27 |
8.4.27 |
Supported upstream |
8.3 |
< 8.3.36 |
8.3.36 |
Supported upstream |
8.2 |
< 8.2.35 |
8.2.35 |
Supported upstream until 2026-12-31 |
8.1 |
All releases | No upstream fix | End of life since 2025-12-31. Migrate or rely on a vendor backport |
8.0 |
All releases | No upstream fix | End of life since 2023-11-26. Migrate or rely on a vendor backport |
7.4 |
All releases | No upstream fix | End of life since 2022-11-28. Migrate or rely on a vendor backport |
7.3 |
All releases | No upstream fix | End of life since 2021-12-06. Migrate or rely on a vendor backport |
7.2 |
All releases | No upstream fix | End of life since 2020-11-30. Migrate or rely on a vendor backport |
7.1 |
All releases | No upstream fix | End of life since 2019-12-01. Migrate or rely on a vendor backport |
7.0 |
All releases | No upstream fix | End of life since 2019-01-10. Migrate or rely on a vendor backport |
5.6 |
All releases | No upstream fix | End of life since 2018-12-31. Migrate or rely on a vendor backport |
5.5 |
All releases | No upstream fix | End of life since 2016-07-21. Migrate or rely on a vendor backport |
5.4 |
All releases | No upstream fix | End of life since 2015-09-03. Migrate or rely on a vendor backport |
Vendor builds differ. Distribution packages (Debian, Ubuntu, RHEL/Alma/Rocky, Amazon Linux, cPanel/CloudLinux) carry their own version strings and backport security fixes without changing the upstream version number, so a build reported as an affected version may already be patched. For PHP 7.4, 8.0 and 8.1 there is no upstream release, but the PHP security team published source patches and several distributions shipped backports. Confirm patch status against your vendor's changelog for the CVE IDs, not the version string alone.
What to do now
1. Find the real version
Check the build serving web requests, not just the CLI. php -v and the
web-facing SAPI are frequently different versions on the same host.
2. Update
Move to 8.5.12, 8.4.27, 8.3.36, 8.2.35 or later for your branch, or to your vendor's patched package. Updating is the only complete fix.
3. Restart workers
Restart Apache, PHP-FPM pools or your container images. A long-lived worker keeps running the old build until it is recycled.
4. Reduce exposure meanwhile
Partial, not complete: session.upload_progress.enabled=0,
fatal_error_backtraces=0 on 8.5, and pm.max_requests=1 on FPM.
Signals to hunt for
The bugs act below the application, so application logs may show little. Look at the web server, PHP-FPM and the process tree, and hunt back to 20-10-2026 when details first leaked. None of these signals proves compromise, and their absence does not prove a host is clean.
| Signal | Where to look | Why it matters |
|---|---|---|
| Oversized or malformed PHPSESSID cookies | Response headers in web server or reverse-proxy logs, especially from hosts that never use sessions | The memory-disclosure bug leaks heap data through this cookie |
| Unusual multipart requests followed by memory errors | Access logs alongside PHP error logs (“Allowed memory size exhausted”) | Every bug begins by forcing an out-of-memory or fatal error |
| Bursts of HTTP 500 from a single source | Access logs, WAF and CDN dashboards | Failed exploit attempts crash PHP workers, which then restart |
| New programs started by PHP workers | EDR or audit logs: children of php-fpm, php-cgi, httpd, apache2, w3wp | After code execution the worker starts processes it never normally runs |
| New or changed .php files | Web roots, upload and temp folders, plus new cron jobs | Persistence survives the patch |
If you find something. Isolate the host, preserve the logs, rebuild from a known-good image, and rotate the application's credentials, API keys and session secrets.
Five things you can check yourself, right now
None of these needs ScruteX or any tool. If you cannot answer one of them with a yes or a no in the next ten minutes, that is the gap.
- Do you know the PHP version serving every public hostname you own? Not the CLI version. The build answering web requests, which is frequently different on the same host.
- Have your PHP workers actually restarted since you patched?
An updated package changes nothing until PHP-FPM, Apache or the container is recycled.
Check with
php -vagainst the running pool, not the package manager. - Do you have a written patch date from every agency, host and platform that runs PHP for you? Pantheon, WP Engine, cPanel and your marketing agency all decide this for you. A verbal assurance is not a date.
- Is any host still on PHP 8.1 or older? Those branches get no upstream fix. If one is internet-facing and cannot move this week, it needs to come off the internet or sit behind a VPN.
- Can you list every internet-facing host you own, including the ones an agency or a former project stood up? Most estates cannot. That is the list this vulnerability is scored against, not the list in your CMDB.
The same check, across every host you own
This page checks one hostname you already thought of. ScruteX runs the same fingerprinting across your whole external estate and keeps running it.
Hosts you did not list
ScruteX maps subdomains and internet-facing assets from the outside, including agency-run and legacy sites, then fingerprints PHP on each one.
End-of-life runtimes, flagged by branch
It matches each observed version against the fixed releases and marks branches that will never receive a fix, rather than only the ones below a patch number.
Re-checked after you patch
A host stays open until the external view changes. The finding closes when the version actually moves, not when a ticket is marked done.
What ScruteX will not see. This is external only. PHP on an internal server, inside a vendor appliance, or on a host that discloses no version will not appear. Those need the internal checks above. Setup is agentless: a domain and a set of keywords.
A finding, in the format you would receive it
Redacted example in the ScruteX finding format. The host name and values do not describe any client.
- Subdomain
- portal.[redacted].com
- Observed version
- PHP 7.4.33
- Current supported
- PHP 8.5.12
- Branch status
- End of life since 28-11-2022
- Evidence
- X-Powered-By: PHP/7.4.33
- Status
- Open
Recommendation. Migrate to a supported branch. Until then, restrict the host to known networks. This branch is unlikely to receive a fix for CVE-2026-109618 or CVE-2026-109619.
Unlisted hosts are a common reason a manual register undercounts exposure. A first external scan can return internet-facing assets the register never listed, including staging environments.
You checked one host. How many others run PHP?
This page checks one domain. ScruteX returns the externally visible PHP hosts and versions across the rest of the estate. Domain only. No signup, no agent.
If this is a wider exposure problem
Threat Insights covers CVE exploitation and the actors using it, which is the part this page only touches for one vulnerability.
Outdated web technologies is the finding type this check produces, run continuously across every host rather than one at a time.
If you want to go deeper or sideways
Passive vulnerability assessment explains how an external check reaches a verdict without touching the host, which is what this page does for PHP.
Dangling subdomains is the adjacent problem: the hosts nobody listed are usually the ones running the oldest PHP.
What we store, and what this cannot tell you
Submitting a domain is not a signup
A single-domain check asks for nothing and creates no contact record. The result is shown on this page and is not written to a database.
Your IP is never stored
Rate limiting uses a salted one-way hash held only in memory for the limit window. We do not record query strings, cookie values or authorisation headers from your site.
This page does not email a report
The result stays on screen. There is no follow-up form and no mailed advisory on this page.
Passive detection has limits
A version string indicates potential exposure, not confirmed exploitability. Confirm against the runtime actually serving your traffic and your vendor's patch status.
Frequently asked questions
What exactly does this tool check?+
It makes one ordinary web request to the domain you submit and reads what the server discloses publicly: response headers such as X-Powered-By and Server, whether a PHP session cookie is issued, and markers in the returned HTML. If a PHP version is disclosed, it is compared against the fixed releases named in the official php-src advisories. Nothing else is sent, and no exploit is attempted.
Does a clear result mean my site is safe?+
Only one result is a positive finding: green, meaning a patched PHP version was actually observed. Everything else is amber and means 'not verified from outside', including when no PHP signals are found at all, which is what most hardened and CDN-fronted sites look like. The only reliable confirmation is the PHP build actually serving requests on your server, checked against your vendor's patch status.
Is this an exploit or an intrusive scan?+
Neither. The check is a single HTTP GET of your site's root document, with strict timeouts and a response-size cap. It never sends payloads, never attempts code execution, never tries to log in, and never enumerates paths or ports. It is indistinguishable from an ordinary page view in your logs.
My server reports an affected version but my distribution says it is patched. Who is right?+
Possibly both. Debian, Ubuntu, RHEL, Alma, Rocky, Amazon Linux, cPanel and CloudLinux backport security fixes without changing the upstream version number, so a package reported as PHP 8.2.20 may already carry the fix. Confirm against your vendor's advisory and the installed package build, not the version string.
What are CVE-2026-109618 and CVE-2026-109619?+
Two critical memory-safety flaws in PHP, published on 21 October 2026 and together nicknamed PHP2Shell. Both are rated CVSS 9.2 and can lead to unauthenticated remote code execution as the web worker user. CVE-2026-109618 is reached through mishandled out-of-memory conditions during request processing; CVE-2026-109619 is a use-after-free on global state left over from a previous request.
What do you do with the domain I submit?+
The check runs when you submit it and the result stays on this page. This site does not write the hostname or the result to a database. Your IP address is not stored. A salted hash is kept only in memory, for the rate limit window, and it disappears when that window ends or the process restarts. Submitting a domain does not create a marketing contact.
Can I check more than one domain?+
This page checks one domain at a time. Submit the hostname, confirm you are authorised to assess it, and the result stays on screen. There is no bulk run and no emailed report on this page. Checking a whole estate continuously is what the ScruteX platform does.