On 21 October 2026 the PHP project released emergency updates for two critical vulnerabilities, nicknamed PHP2Shell. They are not in Laravel, WordPress, or any plugin. They are in the PHP runtime itself, and they can let an attacker run code on your server without logging in. Attack attempts were recorded before the patches were even published. If your company runs anything on PHP, this is the week to confirm that every server has been updated, not just the main one.
What PHP2Shell Is
PHP2Shell is the name researchers gave to two bugs in how PHP manages memory while it handles a web request. The PHP security team rated both at 9.2 on CVSS v4.0, and both can allow unauthenticated remote code execution. In practice that means a crafted HTTP request can make PHP run the attacker's code with the permissions of the web worker account, which can usually read your application files, your .env file, and everything those credentials unlock.
| CVE | Short name | What goes wrong |
|---|---|---|
| CVE-2026-109618 | RCE via out-of-memory corruption | An out-of-memory condition interrupts PHP while internal request data is only partly set up. Request cleanup then treats the invalid data as valid. |
| CVE-2026-109619 | RCE via stale global state | Internal state from one request survives after its memory has been freed. A later request handled by the same worker can use that stale state, which also leaks memory contents. |
The flaws were found by researchers from Calif, OpenAI, Wiz, and others, partly with the help of AI models during a review of the PHP source code. According to Calif, the affected code path goes back as far as PHP 5.4.
Why Secure Application Code Does Not Protect You
Most PHP security advice is about the application: validate input, escape output, keep plugins updated. None of that helps here. PHP says every installation that serves web requests is at risk, including PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP, and LiteSpeed. The risk is highest for mod_php, where a demonstrated exploit triggers the attack before any application code runs. A well-written Laravel application and a ten-year-old custom PHP site are equally exposed if the PHP binary underneath has not been updated.
Why This One Is Urgent
- 17 October: Amazon's honeypots record the first exploitation attempt, four days before public disclosure.
- 20 October: PHP announces an emergency release. Details had already started to leak ahead of the planned coordinated disclosure.
- 21 October: PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35 are released, a day earlier than planned. CISA issues an alert, Cloudflare deploys WAF rules and reports early attacks, and Amazon later describes the flaws as broadly exploited.
- 23 October: PHP publishes an informational advisory on a related, less likely attack path, CVE-2026-115560, to be fixed in the next regular release.
Code claiming to be a PHP2Shell exploit is also circulating. The PHP Foundation said it had not identified a working public exploit at release time, and unverified exploit code is a common way to spread malware. Do not run it against your own servers to "test" them. Check the version instead.
Am I Affected? Check the Version Your Web Server Actually Runs
Running php -v on the server only tells you the version of the command-line binary. The web server may use a different one, especially on servers with several PHP versions installed side by side. Check the binary that serves requests, for example php-fpm8.3 -v, or read the version from a temporary phpinfo page and delete it straight after. Run the check on every host: production, staging, the old admin panel, and the marketing site someone set up three years ago.
| PHP branch | Fixed version | Notes |
|---|---|---|
| 8.5 | 8.5.12 | Supported. On 8.5 the fatal error backtrace setting is also part of the temporary mitigation. |
| 8.4 | 8.4.27 | Supported. |
| 8.3 | 8.3.36 | Supported. |
| 8.2 | 8.2.35 | Security fixes end on 31 December 2026. Plan the upgrade now. |
| 7.4, 8.0, 8.1 | No official release | The PHP security team published minimal source backports. Otherwise rely on your distribution or an LTS vendor, or upgrade. |
| 5.4 to 7.3 | No fix | End of life. Upgrade or take the system offline. |
Linux distributions received the patches in advance and often backport fixes without changing the upstream version number. An Ubuntu or Debian package can be fixed while still reporting an older 8.x.y version. For distribution packages, check the vendor's security notice or package changelog for the two CVE numbers rather than comparing version numbers with the table above.
How to Patch, by Environment
- Ubuntu and Debian: run apt update, then upgrade the PHP packages, for example apt install --only-upgrade 'php8.3*'. If PHP came from the ondrej/php repository, the update comes from that repository, so confirm it has published the fixed build.
- RHEL, AlmaLinux, and Rocky Linux: run dnf upgrade 'php*'. If you use the Remi repository, check its announcement for the fixed builds.
- Docker: pull the updated official php image and rebuild every image based on it. Pinned tags such as php:8.3.30-fpm will never update on their own, so bump them. Then redeploy and run php -v inside the running container.
- Shared hosting and cPanel: PHP is managed by the provider, often through EasyApache or CloudLinux alt-php packages. Ask the provider to confirm in writing that the fixed builds are installed for every PHP version you select.
- Windows: download the fixed release from php.net and replace the installation, then restart IIS or Apache.
- 1List every system that runs PHP, starting with those reachable from the internet. Include containers, staging environments, appliances that bundle PHP, and old applications with little traffic.
- 2Update PHP on each system using the method for that environment, and record who did it and when.
- 3Restart every PHP process, not only the web server: systemctl restart php8.3-fpm for PHP-FPM, systemctl restart apache2 or httpd for mod_php. Workers that keep running still have the old code in memory.
- 4Verify the version from the web server side, not only from the command line, and check that each queue worker or long-running PHP process has been restarted too.
- 5Remove any temporary phpinfo page you created, and keep the session upload progress mitigation in place until the next regular PHP release.
If You Cannot Patch Today
PHP lists several settings that block the confirmed attack paths. It is explicit that none of them makes an installation safe, and that updating is the only complete fix. Use them to buy hours or days, not as a substitute.
- For CVE-2026-109619, set session.upload_progress.enabled=0 in php.ini or the FPM pool, not with ini_set() or .user.ini, and restart every worker. On PHP 8.5, also set fatal_error_backtraces=0.
- For CVE-2026-109618, set memory_limit=-1 in a way the application cannot override, such as php_admin_value in the FPM pool, and pair it with a container or cgroup memory limit so a single request cannot exhaust the server. Do not use RLIMIT_AS or RLIMIT_DATA, which can trigger the vulnerable path.
- Lower post_max_size to 8M if the application has no uploads, or 32M if it does, keep upload_max_filesize below it, and enforce request size and field limits at Nginx, Apache, or the load balancer.
- Put the application behind a WAF with PHP2Shell rules, such as Cloudflare. It only protects traffic that passes through it, so make sure the origin server is not reachable directly.
- If none of this is possible, take internet-facing systems offline or restrict them to a VPN until they are patched, as CISA and CERT-EU recommend.
The 23 October advisory adds one more case. An application that sets session.serialize_handler to php_binary or php_serialize and then switches it to php with ini_set() before session_start() can still be attacked through session upload progress. Very few applications do this, but disabling session upload progress covers it, which is why PHP recommends keeping that setting until the next release.
A mitigation buys time. Only the update closes the hole.
Running PHP 8.1 or Older
PHP 8.1 and earlier no longer receive releases from the PHP project. Because of the severity, the PHP security team published minimal source backports for 7.4, 8.0, and 8.1, but those are for teams that build PHP from source. For everyone else, the options are an updated package from your distribution or an LTS vendor, or an upgrade to 8.2 or newer. If the application cannot run on a supported version, this is the moment to plan that migration, because the next critical PHP bug will not come with backports.
After Patching: Check Whether You Were Already Hit
Patching closes the door but does not remove anyone who came in before it was closed. Since attempts started on 17 October, check internet-facing PHP servers for signs of compromise.
- PHP files that appeared or changed since 17 October in upload and writable folders such as wp-content/uploads, storage, or public/uploads. find /var/www -name '*.php' -newermt 2026-10-17 is a quick first pass.
- New cron entries, systemd services, or SSH keys belonging to the web server user.
- Admin accounts in the application that nobody on the team created.
- Unexpected outbound connections or sustained CPU use, a common sign of a cryptominer.
- Spikes of PHP-FPM worker crashes or segmentation faults in the logs, and unusual requests in the access log around the same time.
If you find anything, treat the server as compromised. Rotate every secret the web user could read, including database passwords, API keys, and the application key, and rebuild the server from a clean image rather than deleting the files you happened to find.
Make Sure Someone Owns the PHP Version
Incidents like this expose a gap that has little to do with code. Many companies know who built their application but not who is responsible for updating the PHP underneath it, especially after the original vendor has moved on. Keep an inventory of where PHP runs, which version each system uses, how it is updated, and who owns it. That turns the next emergency release into a routine task. If you need help assessing or patching your PHP servers, our managed service team can review them with you.
Key takeaways
- PHP2Shell is two critical flaws in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, that allow unauthenticated remote code execution regardless of how secure your application code is.
- Update to PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or to a distribution package that lists both CVEs as fixed, then restart every PHP worker.
- Check the version the web server runs, not only php -v, and cover every host including staging and forgotten sites.
- Configuration mitigations and WAF rules only buy time. Disable session upload progress until the next PHP release either way.
- Exploitation began on 17 October, so check for unknown PHP files, cron jobs, and admin users, and rotate secrets if anything looks wrong.


