PHP2Shell for Developers: The Technical Summary With Every Link
PHP2Shell for Developers: The Technical Summary With Every Link

As of 23 October 2026, PHP2Shell is two memory-safety bugs in the PHP engine, CVE-2026-109618 and CVE-2026-109619, fixed upstream in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on 21 October 2026. Exploitation attempts are widely reported. No confirmed successful compromise is publicly documented, and neither CVE is in CISA's KEV catalog (version 2026.10.23). A related informational issue, CVE-2026-115560, affects even patched builds until PHP's next regular release.
The short version for developers: ship a fixed PHP build to every runtime that serves web requests, restart or replace every worker, rebuild every image that carries its own PHP, and verify the build actually serving traffic. Until the next regular release, keep session.upload_progress.enabled=0. No application, framework or CMS update fixes it.
This page is a reference. Each section is a summary that links to the detailed guide. It leaves out exploit mechanics on purpose.
Key Takeaways
- Both CVEs score 9.2 (CVSS 4.0) from PHP as the CNA. NVD's CVSS 3.1 scores are 9.8 and 8.1. No authentication is required.
- Official releases exist only for 8.2 to 8.5. For 7.4, 8.0 and 8.1, PHP published source-only backport branches. Older branches depend on vendors.
- mod_php is the highest-risk server API. PHP-FPM, php-cgi, LiteSpeed and FrankenPHP are all in scope.
- Version strings lie on distro builds. Verify with the package changelog, the build date or, on official upstream builds only, the new memory_hard_limit_percent directive.
- Containers and bundled runtimes (FrankenPHP static binaries, custom images, Vapor) need a rebuild or redeploy. A host update doesn't reach them.
- ini mitigations are partial and only work in php.ini, FPM pools or server config. ini_set() and .user.ini don't help.
The CVEs at a Glance
| Item | CVE-2026-109618 | CVE-2026-109619 | CVE-2026-115560 |
|---|---|---|---|
| Advisory | GHSA-w8hw-w9fx-j79w | GHSA-6wmf-4rv5-p3rp | php.net informational advisory, 23 Oct |
| PHP's title | RCE via OOM corruption | RCE via stale global state | Session upload progress |
| Area | Out-of-memory handling during multipart request parsing | Request state that survives into the next request on the same worker | Unusual runtime serialize-handler change with upload progress on |
| Score | 9.2 (PHP, v4.0); 9.8 (NVD, v3.1) | 9.2 (PHP, v4.0); 8.1 (NVD, v3.1) | No NVD record as of 23 Oct |
| Fixed in | 8.5.12, 8.4.27, 8.3.36, 8.2.35 | Same releases | Next regular release; keep upload progress off |
| Deep dive | CVE-2026-109618 explainer | CVE-2026-109619 explainer | Covered in the mitigations guide |
The CWEs on both advisories are CWE-416, 755, 824, 1325 and 1419. Wiz's blog maps its four bug names to the CVEs differently from PHP. Use PHP's mapping. Both advisories credit researchers from Calif, Wiz and OpenAI, plus a fourth reporter (tomash-areion). Calif reported first, on 11 August 2026. Primary sources: GHSA-w8hw, GHSA-6wmf and the php.net announcements. For the plain-English version for clients, send them to what PHP2Shell is. Exploitation reports conflict, and our exploitation status tracker follows them.
Versions: Fixed, EOL and Backported
| Branch | PHP2Shell fix | Security support ends | Guide |
|---|---|---|---|
| 8.6 (RC) | RC4 includes the fixes; RC5 planned 5 Nov 2026 | Not released | See 8.5 guide |
| 8.5 | 8.5.12 (also ships about 120 lines of other bug fixes) | 31 Dec 2029 | PHP 8.5 |
| 8.4 | 8.4.27 (also ships other bug fixes) | 31 Dec 2028 | PHP 8.4 |
| 8.3 | 8.3.36 (fix only) | 31 Dec 2027 | PHP 8.3 |
| 8.2 | 8.2.35 (fix only) | 31 Dec 2026 | PHP 8.2 |
| 8.1 | Source backport branch; vendor builds keep 8.1.34 | Ended 31 Dec 2025 | PHP 8.1 |
| 8.0 | Source backport branch; vendor builds keep 8.0.30 | Ended 26 Nov 2023 | PHP 8.0 |
| 7.4 | Source backport branch; vendor builds keep 7.4.33 | Ended 28 Nov 2022 | PHP 7.4 |
| 7.3 and older | No official backport; vendor builds only | Long ended | PHP 7 and older |
PHP's advisories list only 8.2 to 8.5 as affected, but NVD's range for CVE-2026-109619 starts at 5.4.0, and several researchers say older branches are affected too. Assume every branch is. Release-by-release detail is in our fixed versions guide. Planning a branch jump? Read upgrading old PHP safely. One known regression to watch for: php-src issue 24488 reports a SimpleXML double free in 8.4.27 and 8.5.12. It is a stability bug, not a bypass, and was closed on 22 October. php.net has not said which release ships the fix.
Exposure by Server API
php.net puts "all PHP installations serving web requests" in scope. The advisories differ on how exposed each server API is:
| Server API | What the advisories say | Guide |
|---|---|---|
| Apache mod_php | Highest risk. 109618 is validated over HTTP with default limits, before application code runs. | mod_php |
| PHP-FPM | 109618: susceptible by source analysis, no complete FPM exploit shown. 109619: session lifecycle RCE validated. Conditionally exposed through PHP_VALUE or PHP_ADMIN_VALUE that emit diagnostics. | PHP-FPM, nginx |
| LiteSpeed (LSAPI) | LSAPI "models FPM," with application-specific exploits "likely but unvalidated." PHP runs detached from the web server. | LiteSpeed |
| FrankenPHP | "likely susceptible to application-independent attacks" (109618). Static binaries bundle their own PHP. | FrankenPHP |
| php-cgi | In scope per php.net. No server-API-specific analysis published. | php-cgi |
OPcache appears in Wiz's research only as one exploit path. No advisory asks for an OPcache step beyond the restart; see PHP2Shell and OPcache.
Verify the Build That Serves Traffic
The command-line php binary can differ from the one PHP-FPM or Apache runs, and distributions backport fixes without changing the version string. Check through the web server, then prove the fix with one of these. The commands are examples; replace package names and versions with your own:
apt-get changelog php8.3-fpm | grep -E 'CVE-2026-(109618|109619)' (Debian or Ubuntu)
rpm -q --changelog php-fpm | grep -E 'CVE-2026-(109618|109619)' (RHEL family)
ps -C php-fpm -o pid,lstart (worker start times; adjust the process name to your system)
On official 8.2.35 to 8.5.12 builds, the new memory_hard_limit_percent directive exists. Run through the web server, ini_get('memory_hard_limit_percent') returns an empty string when the directive exists and false when it doesn't. PHP's manual says an unrecognized directive means "the PHP version in use is affected." That holds only for official upstream builds. The 8.1 source backport doesn't add it, and distro backports may not either. If you use a temporary phpinfo() page, delete it afterwards. Our tools help here: the free exposure check and the PHP version lookup. The full method for each platform is in how to check your PHP version.
Restart, Rebuild, Redeploy
Installed but not loaded is not patched. PHP says to "restart every worker." Our restart guide has the commands for each setup. For pipelines and platforms:
- Docker official images: the 8.5.12, 8.4.27, 8.3.36 and 8.2.35 tags were pushed on 21 October. The 8.1, 8.0 and 7.4 tags have not been rebuilt, so there is no fixed official image for 8.1 or older. The wordpress, drupal and joomla latest images were rebuilt on 22 October.
- Your images: rebuild with a fresh base pull. FrankenPHP's docs warn that Docker "can have a cache layer" and suggest the --no-cache option. docker compose pull alone doesn't start new containers; docker compose up recreates containers whose image changed.
- Kubernetes: with imagePullPolicy IfNotPresent, an image is pulled "only if it is not already present locally." Kubernetes advises against :latest in production. Use a new tag or digest, then roll the deployment (for example, kubectl rollout restart deployment/my-app).
- Laravel: Laravel Cloud patched in place. Forge needs "Update PHP" on each server. Vapor needs a redeploy (custom or Docker runtimes need a new deployment). Octane's FrankenPHP binary bundles its own PHP and must be reinstalled. See PHP2Shell and Laravel.
- Clouds: Google Cloud says "Container images you build yourself are your responsibility." App Engine flexible must be redeployed, and Cloud Run services without automatic base image updates must be rebuilt. Azure App Service doesn't patch custom containers. AWS Lightsail needs new instances from updated blueprints.
Interim Mitigations, Where They Actually Apply
PHP's line: "There are no complete mitigations, updating is the only safe choice." If you must hold for a few hours, the options are below. Our interim mitigations guide covers side effects, and the php.ini generator drafts the settings.
| Setting | CVE | Caveat |
|---|---|---|
| session.upload_progress.enabled=0 | 109619, 115560 | Blocks confirmed session paths only. Keep it off after patching. |
| fatal_error_backtraces=0 | 109619 | PHP 8.5 only. Blocks the confirmed backtrace path only. |
| memory_limit=-1 via php_admin_value | 109618 | Removes the memory cap. Use a container or cgroup limit, never RLIMIT_AS or RLIMIT_DATA. On fixed builds, -1 also disables the new hard limit. |
| post_max_size 8M (no uploads) or 32M | 109618 | Breaks larger uploads. Keep upload_max_filesize below it. |
| Frontend limits on body size, fields, parts, headers, nesting | 109618 | Must also cover requests without a usable Content-Length. |
| pm.max_requests=1 | 109619 | Severe performance cost. |
Settings must load before request parsing: php.ini, the FPM pool or server configuration. PHP is explicit: "Do not rely on ini_set() or FPM .user.ini." A WAF is a layer, not a fix.
What to Fix in Your Own Code and Config
The engine fix is the remedy. GHSA-6wmf also points at things in application code and configuration that widen exposure:
- Remove invalid or deprecated settings applied per request, such as php_value lines in .htaccess or PHP_VALUE from nginx, that emit warnings before request initialization. Hiding diagnostics with error_reporting, display_errors or @ "does not help."
- Fix attacker-reachable fatal errors and execution timeouts, "including failures in callbacks, upload or import processing and cleanup."
- For CVE-2026-115560, check whether your code switches session.serialize_handler to php with ini_set() before session_start(). PHP says only that pattern is affected. If you don't need upload progress, turn it off anyway.
- If the application never takes multipart uploads, GHSA-w8hw suggests blocking multipart requests "at the frontend before they reach PHP."
Framework and app specifics live in the app guides: Symfony, CodeIgniter and CakePHP, custom PHP apps, WordPress, Drupal, Joomla, WooCommerce, Magento, Moodle, Nextcloud and WHMCS. The Dutch NCSC keeps a community software inventory. Most "Vulnerable" rows there mean "runs on PHP," not "vendor confirmed." Headless stacks still need their PHP backend patched; see our headless security guide. Our guide to plugin and package supply chain security covers the dependencies you inherit.
Detection and Response
- Look back to at least 17 October 2026, the earliest attempt Amazon reported.
- Signals named by Wiz, Beazley, Datadog and Sophos include unusual multipart requests (including to endpoints that don't take uploads), requests containing PHP_SESSION_UPLOAD_PROGRESS, memory-exhaustion errors logged "in Unknown on line 0," worker segfaults and churn, oversized PHPSESSID cookies, web workers spawning shells, and new PHP files in web roots.
- Clean logs prove nothing. GHSA-6wmf says "absence of an error in logs is not proof of safety," and Bitdefender notes a successful exploit "can return HTTP 200."
- Preserve logs before rebuilding. If compromise is suspected, rotate the secrets the PHP process could read, such as database credentials, API keys and cloud credentials.
- Don't rely on IOC lists. The few IP addresses AWS published include shared anonymization infrastructure, and AWS says to investigate them rather than block them. Treat public proof-of-concept repositories as untrusted code.
The step-by-step check is in "was my site hacked?", and our incident response plan covers the first hour. Hosting-side questions are in PHP2Shell on shared hosting and what to ask your host. For everything else, see the PHP2Shell FAQ.
Conclusion
For developers, PHP2Shell has one remedy and many places to apply it. Get a fixed engine on every web-serving runtime, load it with a restart or redeploy, prove it with a changelog or build check, keep upload progress off until the next release, and clean up per-request config that widens exposure. If you need another pair of hands on a fleet of servers or images, our emergency PHP patching team works with in-house developers. Every PHP2Shell guide is in our PHP2Shell Resource Center.
Frequently Asked Questions
Is the CLI affected?
PHP scopes the risk to "all PHP installations serving web requests." The CLI binary uses the same engine, so patch it with the rest. The bigger reason to care about the CLI is that it can report a different version from the one serving traffic.
Does php -v prove I'm patched?
Only on official upstream 8.2.35, 8.3.36, 8.4.27 or 8.5.12 builds, and only for the binary you ran. Distro and vendor backports keep old version strings. Use the package changelog or build date for those.
Do I need to clear OPcache?
No advisory asks for it. Restarting PHP-FPM, Apache or the PHP process starts fresh workers from the new binary, which covers it.
Will a WAF rule protect me until I patch?
Partly. CISA says a WAF "may provide some protection." Cloudflare's rule covers sites that use PHP's default upload progress field name. Origins reachable directly by IP bypass the WAF entirely.
Can I keep memory_limit=-1 after patching?
You can, but on fixed builds -1 also removes the new hard memory limit, so a runaway request can exhaust server memory. Restore a finite limit once the patched build is live, unless you have a container or cgroup limit in place.
Should I upgrade the branch or just patch?
Patch first, today, on the branch you run. Then plan a move off 8.1 or older, and off 8.2 before its 31 December 2026 end of life.
Put this into action with eSEOspace
We help businesses grow with maintenance & support that actually performs. Explore the services behind this guide:
Get a FREE Audit
We'll perform a comprehensive SEO, AEO, GEO & CRO audit of your website — completely free — and show you exactly how to outrank your competitors.
Don't have a site yet? Get in touch →
Get a FREE GEO/AEO/SEO Audit
We'll analyze your site's SEO, GEO, AEO & CRO — completely free — and show you exactly how to get found across Google and AI answers.
Don't have a site yet? Get in touch →
Great — your audit is on the way!
We'll send your free SEO/GEO/AEO/CRO audit within the next few hours. Where should we send it?
You're all set! ✓
Your free audit is being prepared — check your inbox in the next few hours. Talk soon!
On this page





