php2shell: The PHP Bug That Fires Before Your Code Runs
Aerovant Technologies Security Team

Most web vulnerabilities live in your code: a forgotten input check, a bad plugin, a weak password. php2shell is different. It lives in PHP itself, and on some servers it fires before a single line of your application runs.
On 21 October 2026, the PHP project shipped emergency fixes for two critical flaws, CVE-2026-109618 and CVE-2026-109619, nicknamed php2shell. An unauthenticated attacker on the internet can send crafted requests and potentially run code on your web server. No login, no user click, no vulnerable plugin required.
If you run WordPress, Laravel, Magento, Drupal or any custom PHP application, read on.
What happened
The bugs were found by researchers at Calif and reported to PHP for coordinated disclosure. The plan was a quiet release on 22 October. It did not go to plan: attackers were probing before the patch existed, details leaked, and PHP brought the release forward by a day.
| Date (2026) | Event |
|---|---|
| 22 Oct | Vendors update advisories. Neither CVE is yet in CISA’s Known Exploited Vulnerabilities catalog |
| 21 Oct | PHP releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35 (14:00 UTC). Honeypots record exploitation attempts the same day |
| 20 Oct | Details leak on social media. PHP announces an emergency release, a day earlier than planned. watchTowr publicly confirms the bugs are real |
| 17 Oct | Amazon’s MadPot honeypot records an attempt, four days before disclosure |
| Earlier | Linux distributions and LTS vendors receive patches in advance |
The 17 October hit is the detail that matters. Someone had a working idea of the attack before most defenders knew there was anything to patch.
How the two bugs work
Both flaws are memory-safety bugs in PHP’s C core, in the part that handles each incoming request. That is why they are so dangerous: they sit below every framework and every line of application code.
CVE-2026-109618: out-of-memory corruption
When PHP runs out of memory, it can abandon a request halfway through setting up its data. Cleanup code then runs over that half-built data as if it were complete.
- The attacker sends a crafted multipart request (the format used for file uploads and forms).
- The request pushes PHP into an out-of-memory condition, even within normal configured size limits.
- PHP stops mid-allocation, leaving partly initialised structures in memory.
- Cleanup trusts those structures, and the resulting memory corruption can be turned into code execution.
On Apache mod_php this all happens while the request body is parsed, before your application is called.
CVE-2026-109619: use-after-free across requests
PHP workers are reused. One process serves request after request, and it is supposed to wipe its state in between.
- Request A triggers a fatal error or timeout that interrupts normal cleanup.
- Some global state still points at memory that has already been freed.
- The same worker picks up request B, which reads that stale pointer.
- The attacker shapes what sits in the freed memory, leading to memory disclosure or code execution.
Session upload progress, which is enabled by default, is one known path that consumes this stale state. PHP lists memory disclosure as a confirmed impact.
What an attacker gets
Code execution with the privileges of the web server user (often www-data, apache or nginx). From there they can read the application’s configuration, including database passwords and API keys, plant a web shell, and move deeper into the network.
Who is affected
Every PHP installation that serves web requests is in scope. The vulnerable code path dates back to at least PHP 5, so age is no protection.
| PHP branch | Status | Action |
|---|---|---|
| 8.5 | Affected below 8.5.12 | Upgrade to 8.5.12 |
| 8.4 | Affected below 8.4.27 | Upgrade to 8.4.27 |
| 8.3 | Affected below 8.3.36 | Upgrade to 8.3.36 |
| 8.2 | Affected below 8.2.35 | Upgrade to 8.2.35 |
| 7.4, 8.0, 8.1 | All versions affected; no official release | Distribution or LTS vendor package, or PHP’s source backports. Plan a move to 8.2+ |
| 5.x to 7.3 | Affected, no fix at all | Upgrade to a supported branch, or isolate the server |
How PHP runs matters. PHP-FPM, php-cgi, FrankenPHP and LiteSpeed are all affected. Apache with mod_php is the highest-risk setup, because PHP parses the malicious request inside the web server before any application code, WAF logic in your app, or authentication check gets a chance to run.
A distribution caveat. Ubuntu, Debian, RHEL and similar distributions often backport security fixes without changing the version number. A server that reports 8.1.2 may be patched; one that reports a newer number may not be. Check your distribution’s advisory or package changelog for the CVE IDs rather than trusting the version string alone.
Is it being exploited?
Attackers are trying. Whether they are succeeding at scale is where vendors disagree.
| Source | What they report |
|---|---|
| Amazon Threat Intelligence | First attempt on 17 Oct, four days before disclosure; more attempts from several sources on 21 Oct. Amazon says it is unclear whether any of them would have worked |
| watchTowr, Cloudflare | Exploitation attempts observed on their sensor networks |
| Rapid7 | Many attempts, but no confirmed in-the-wild exploitation; public proofs of concept work only on specific OS, PHP version and web server combinations |
| PHP Foundation | Found no functional public exploits at release |
| CISA KEV | Not listed as of 22 Oct |
For a defender, the disagreement does not change the decision. Memory-corruption exploits start out fragile and become reliable over time. Rapid7 itself warns a portable technique could appear at any moment. Treat this as an emergency patch, not a next-sprint ticket.
Why this hits Indian startups and SMEs hard
PHP quietly runs a large share of India’s business websites: WordPress company sites, WooCommerce stores, school and hospital portals, and Laravel or CodeIgniter apps built by agencies years ago. Three patterns make php2shell especially risky here.
- The “built once, never touched” site. An agency delivered the site, the contract ended, and nobody owns the server. It may still run PHP 7.x, which will never get an official fix.
- Self-managed VPS and cloud servers. A WordPress site on an EC2 instance, Lightsail, DigitalOcean or Hetzner box is patched by nobody unless you do it. Managed and shared hosts are patching for their customers; a VPS owner is the host.
- Shared servers holding real data. The same box often hosts the website, an admin panel and a customer database. Code execution as the web user is frequently enough to read
wp-config.phpor.envand walk away with credentials.
If your answer to “which PHP version is our website on?” is “I’d have to ask someone”, start with the next section.
Check your exposure in 10 minutes
On WordPress: go to Tools → Site Health → Info → Server to see the PHP version. On managed or shared hosting, check your host’s status page or ask support directly: “Have you applied the 21 October PHP security release?”
On a server you manage, run these as an admin:
# 1. PHP version (CLI)
php -v
# 2. How PHP is served: is Apache loading mod_php? (highest risk)
apachectl -M 2>/dev/null | grep -i php
# 3. Is PHP-FPM running, and which version?
ps aux | grep -E 'php-fpm|php[0-9.]*-fpm' | grep -v grep
# 4. Debian/Ubuntu: installed PHP packages and whether the fix is in
dpkg -l | grep -E '^ii +php'
apt changelog php8.3-fpm 2>/dev/null | grep -E 'CVE-2026-10961[89]'
# 5. RHEL/Rocky/Alma: package changelog
rpm -q --changelog php-fpm | grep -E 'CVE-2026-10961[89]'Adjust package names to your version (for example php8.2-fpm or libapache2-mod-php8.1).
Watch out for:
- More than one PHP. Servers often run several versions side by side (control panels, old sites). Check each one.
- CLI is not the web.
php -vshows the command-line binary. The web server may use a different version and a differentphp.ini. Confirm with a temporaryphpinfo()page, then delete it immediately. - Containers. Check the PHP version inside your images (
docker run --rm <image> php -v), not just the host. Rebuild and redeploy; a patched host does not patch the image.
Fix it
Patching is the only complete fix. Everything else only buys time.
1. Patch, then restart every worker
- Distribution packages: update through your package manager (
apt upgrade/dnf upgradeon the PHP packages). - Built from source or official images: move to 8.5.12, 8.4.27, 8.3.36 or 8.2.35, and rebuild containers.
- PHP 7.4 to 8.1: use your distribution’s or LTS vendor’s patched package, and schedule the move to 8.2+.
- PHP 7.3 or older: there is no fix. Upgrade, or take the server off the internet until you can.
Then restart PHP-FPM and Apache. Updated files on disk do nothing while old workers are still running in memory.
Internet-facing servers come first, and Apache mod_php servers first among those.
2. If you cannot patch today
These settings reduce exposure but do not make a server safe. Set them in php.ini, the FPM pool config or the web server config, then restart all workers:
; CVE-2026-109619: close the session upload progress path
session.upload_progress.enabled = 0
; CVE-2026-109618: avoid the out-of-memory path
; (enforce so applications cannot override it)
memory_limit = -1
; PHP 8.5 only
fatal_error_backtraces = 0Also:
- Use container or cgroup memory limits as the outer guard, since
memory_limit = -1removes PHP’s own cap. - Bound request sizes at the edge. Keep
post_max_sizemodest (8M or 32M) withupload_max_filesizebelow it, and limit body size, multipart parts and headers in Nginx, Apache or your load balancer. - Block multipart requests on endpoints that never take uploads.
- Turn on WAF rules. Cloudflare has deployed rules on all plans. On paid plans, make sure managed rules are set to block, not just log. This only protects traffic that actually flows through the WAF.
- Isolate what you cannot fix. CERT-EU recommends isolating internet-facing applications until a fix is applied and verified.
3. What not to do
- Don’t use
ini_set()in application code or.user.inifor these settings. They apply too late. - Don’t set
RLIMIT_ASorRLIMIT_DATAprocess limits. They can push PHP into the very allocation-failure path you are trying to avoid. - Don’t treat silent logs as proof of safety. Hiding errors with
display_errors,log_errorsor@does not remove the exposure. - Don’t assume your host has patched. Ask, and get a yes in writing.
Detect and verify
No vendor has published reliable indicators of compromise for php2shell yet. Until they do, hunt for the side effects that memory-corruption attacks and post-exploitation usually leave. Treat these as leads to investigate, not proof.
Signs worth investigating, from 17 October onwards:
- Worker crashes. PHP-FPM logs showing
child ... exited on signal 11 (SIGSEGV), or ApacheSegmentation faultentries, especially in bursts. - Out-of-memory fatals (
Allowed memory size ... exhausted) on endpoints that normally never hit them. - Unusual multipart POSTs in access logs: to pages that never accept uploads, from a single IP, or in rapid repetition.
- Unexpected child processes of the web user, such as
sh,bash,curl,wget,pythonorncspawned byphp-fpmorapache2. - New or changed files in the web root or upload folders, especially
.phpfiles where none should be. - Outbound connections from the web server to unfamiliar IPs.
After patching, verify:
- Each server’s PHP package or version shows the fix, per the distribution changelog.
- All PHP workers were restarted after the update (check process start times).
- Containers were rebuilt from patched base images and redeployed.
- If you found any of the signs above, rotate secrets: database passwords, API keys and the keys in
wp-config.phpor.env. Then scan for web shells. A patched server can still have an attacker inside.
The lesson beyond this CVE
php2shell will be patched and forgotten within weeks. The conditions that make it dangerous will not.
- You cannot patch what you don’t know you run. Keep an inventory of every server, its runtime version and who owns it.
- End-of-life software is a standing liability. PHP 7.x will never get an official fix for this or the next bug.
- Defence in depth still matters. The web user should not be able to read every secret; databases should not trust the web server blindly; outbound traffic from web servers should be restricted.
- Someone has to be watching. The first attack landed four days before the advisory. Only monitoring would have caught it.
How Aerovant can help
If you are unsure where PHP runs in your environment, or whether last week’s traffic was more than noise, our team can help:
- Exposure check: identify internet-facing PHP servers, versions and how they are served.
- Patch and hardening support for self-managed servers, cloud VMs and containers on AWS.
- Compromise assessment: log review and web shell hunting on servers that were exposed.
- VAPT and Managed SOC to find the next weak point before an attacker does, and to watch for it after hours.
Write to admin@aerovanttech.com or get in touch.
This article reflects public information as of 23 October 2026. Details may change as vendors publish further analysis; always follow your distribution’s and PHP’s official advisories.
Sources
- Amazon Threat Intelligence: PHP2Shell exploitation identified in MadPot prior to public disclosure
- Bitsight: CVE-2026-109618 and CVE-2026-109619 (PHP2Shell)
- Rapid7: CVE-2026-109618 and CVE-2026-109619, critical unauthenticated RCE in PHP
- Tenable: php2shell frequently asked questions
- watchTowr: PHP2Shell FAQ
- Codeable: What WordPress site owners need to do
- Google Cloud: Responding to core PHP vulnerabilities