PHP2Shell, From Zero: The Bug Under the Website, and What Actually Fixes It

2026-10-27

Ten-second version, drafted 25 October 2026. Fixed releases: PHP 8.5.12, 8.4.27, 8.3.36, or 8.2.35. Then restart every PHP worker. A WordPress, Drupal, or plugin update is not this fix. If you cannot patch, take the site off the public internet. That is the NSA and CISA advice, not a metaphor.

If you used the web on 21 October 2026, a language you have probably never installed may be why a government page, a wiki, or a shop blinked off. The language is PHP. The pair of bugs is nicknamed PHP2Shell. The fixes shipped the same day. A lot of servers still have not taken them.
This is the whole story from the first moving part. Scary words are translated the moment they appear. There is no exploit recipe. The point is to know what broke, which headline numbers were inflated, and which action actually closes the hole.

You do not have PHP. The website does.

Mind map of PHP2Shell: PHP runs under the website, two memory bugs, fixed in 8.5.12 8.4.27 8.3.36 8.2.35, restart workers, WordPress update is not the fix, offline if unpatched

A website is not a file sitting on your laptop. You type an address. Your browser (the app that draws the page: Chrome, Safari, Firefox, or the one built into your phone) sends a request (a short message that means “please give me this page”) across the internet. A server (a computer left on in a data centre, whose job is to answer those messages) receives it and sends a document back.
That document is HTML (HyperText Markup Language, the tags that say “this is a heading” and “this is a link”). HTML is the result, not the chef. A Wikipedia article is not a finished file waiting in a folder. It is assembled when you ask. On a huge share of ordinary websites, the program that assembles it is PHP.

The stack, in one pass

Read this top to bottom. Each row is a job. PHP2Shell sits in row 3, which is why updating the thing in row 4 often does nothing.

StepNamePlain meaning
1BrowserAsks for the page. Not affected. You install nothing.
2Web serverApache, Nginx, or LiteSpeed. The receptionist. It accepts the connection and hands the request to PHP.
3PHPThe language engine, in a version such as 8.3 or 7.4. Both bugs live here.
4The appWordPress, Drupal, Laravel, a shop, a custom site. Your code can be careful and still be exposed, because the bug can fire before the app runs.
5The answerHTML, plus anything pulled from a database (an organised store of posts, users, and orders). What you see.

One more word before the bugs make sense. A worker (one PHP process that stays alive and handles request after request, instead of starting from zero every time) is why the second bug exists. Picture one cook and a queue of tickets. The cook is not replaced between orders. If a burnt ticket is left on the counter, the next order can be cooked from the wrong ticket.

What the letters PHP mean

PHP stands for PHP: Hypertext Preprocessor. The first P stands for PHP. A name that contains itself is a recursive acronym. It started in the mid-1990s as a way to make pages that change per visitor, instead of pages that are identical for everyone. It is open source (the code is public). A non-profit, the PHP Foundation, plus volunteers and companies that depend on it, maintains it. It is free. It sits under WordPress, and WordPress sits under a very large share of blogs, newsrooms, and small-business sites. Wikimedia, the organisation behind Wikipedia, runs PHP too. So do many government sites, shops, and forums that never mention the fact.
You will not find PHP in your phone settings. It is not a browser extension. If you pay a host (a company that rents you the server, or a slice of one) and click “install WordPress”, the host installed PHP for you.

The 70 percent claim, said so it stays true

Headlines said PHP powers about 70 percent of the world’s websites. The careful number is narrower, and it is still enormous.
W3Techs, a long-running survey of web technologies, reported on 25 October 2026 that PHP is used by 69.2 percent of websites whose server-side language can be identified. Server-side means the code that runs on the server, as opposed to JavaScript (a different language) that runs in the visitor’s browser. Sites that hide their language, and sites that are just static files, are not in that denominator. Nextgov, citing the same survey family, used that caveat. The BBC quoted security firm Wiz saying “70 percent of the world’s websites”, which is the rounded, looser version.
Use 69.2 percent of identifiable server-side sites. Do not say “most of the internet” as if every page, app, and video stream were PHP. A streaming service is not PHP. Your bank’s mobile app may not be PHP. A frightening share of ordinary websites is.
On that same W3Techs page, the sites that do use PHP split like this on 25 October 2026:

PHP major versionShare of PHP sitesStill getting official security fixes?
865.5%Only 8.2, 8.3, 8.4, and 8.5. Versions 8.0 and 8.1 sit inside this 65.5% and are already unsupported.
726.8%No
57.7%No
40.1%No

A Japanese analysis published 22 October, combining W3Techs version shares with PHP’s support calendar, estimated that about 48.4 percent of PHP sites were on a branch PHP itself no longer updates. Treat 48.4 percent as their arithmetic, not as a W3Techs headline. The direction is not in doubt. A very large minority of PHP sites cannot install the official packages below, because those packages do not exist for their branch.

A vulnerability is a mistake an outsider can use

A vulnerability (a flaw that lets someone do something the designer did not allow) is not the same as a bug that merely crashes a page. These two are CVE-2026-109618 and CVE-2026-109619. A CVE (Common Vulnerabilities and Exposures, a public catalogue number so that everyone means the same bug) is only a label. Together they were nicknamed PHP2Shell. The nickname escaped from a leaked screenshot and a demo video. It is not an official PHP product name.
Both are scored 9.2 on CVSS v4. CVSS (Common Vulnerability Scoring System, a shared scale from 0 to 10) version 4 calls 9.0 and above critical. The vector published with the advisory is CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H. One piece at a time:

  • AV:N means the attacker can try over the network. They do not need a badge for the data centre.
  • AC:H means attack complexity is high. It is not one obvious button on every server. The build and the memory layout matter.
  • AT:P means some attack requirements are present. Success depends on conditions, not on merely knowing the address.
  • PR:N means no privileges. No password. No account.
  • UI:N means no user interaction. Nobody has to click a poisoned link.
  • VC:H, VI:H, and VA:H mean that if it works, the hit is high on confidentiality (who can read data), integrity (who can change data), and availability (whether the service stays up).
    So 9.2 does not mean every PHP site was taken over on Tuesday. It means that if an attacker wins the hard conditions, they own the process. The PHP project’s own line, quoted by PHP News: every PHP installation that serves web requests is in scope. The highest demonstrated risk is Apache with mod_php (PHP built into the Apache web server, so it runs inside Apache’s own processes), where an unauthenticated request can trigger the attack before any application code runs.
    Remote code execution (running the attacker’s program on your server, often shortened to RCE) is the end state. Unauthenticated (no login) is why agencies said: if you cannot patch, take the site offline. A firewall rule inside WordPress never sees a request that PHP mishandles before WordPress starts.

The two bugs, without a recipe

Both are memory-safety bugs. Memory (the server’s short-term workspace) holds the request while PHP handles it. A pointer (a note that says “the data is at this spot”) is safe only while that spot still holds what you think it holds. These bugs free the spot, or leave it half-built, and then trust the note.

CVE-2026-109618, the bailout bug

PHP lets an operator set memory_limit, a ceiling on how much workspace one request may use. Hit the ceiling and PHP bails out, instead of letting one visitor eat the whole machine. The flaw is in that bailout. If the abort happens while PHP is still building its internal picture of the request, cleanup can treat a half-built picture as finished.
The confirmed path uses a crafted multipart request. Multipart (the format browsers use when a form includes a file upload, also called multipart/form-data) is ordinary web traffic. “We do not have an upload button” is not a comforting sentence. PHP and outside researchers confirmed code execution against mod_php with default limits. The PHP Foundation also said RCE was confirmed on PHP-FPM through application-level paths. PHP-FPM (PHP-FastCGI Process Manager) is the usual modern way to run PHP as its own pool of workers behind Nginx or Apache.
Sansec and others also described a data leak from this bug, in the family of Heartbleed (the 2014 flaw that let outsiders read leftover memory, including secrets). The request shapes are public. Copying them does not help you patch, so they are not here.

CVE-2026-109619, the leftover-ticket bug

Back to the cook who is not replaced between orders. A worker keeps some state across requests: error information, session machinery, extension data. A session (the server’s memory that “this is the same visitor as last time”) is normally started by the app. One path here, session upload progress, is on by default and does not need the app to call session_start.
If a request dies in a fatal error (a stop so severe that PHP abandons the request), memory can be freed while the worker still holds a pointer into it. The next request on that same worker uses the stale pointer before PHP resets it. PHP confirmed code execution through the fatal-error backtrace path on mod_php, and through the upload-progress path on both mod_php and PHP-FPM.
Hiding errors does not help. The advisory says that changing error_reporting, silencing a line, or turning off display_errors or log_errors does not protect you.
There is no complete workaround. PHP release managers said configuration changes are not a fix. A setting can block one demonstrated path and buy hours. It does not make the installation safe, because other paths exist, including paths that run before your code.

How it was found, and why the public heard late

The surprising part is not that PHP has a memory bug. Software this old, touched by every request, has sharp edges. The surprising part is the calendar.

WhenWhat happened
2024A core developer working with the PHP Foundation sees the shape of the problem while fixing an audit finding. The fix stalls.
11 August 2026Calif, working with OpenAI, reports remote code execution with the same root cause.
24 August 2026Wiz reports the bugs.
18 September 2026OpenAI reports more ways to trigger them.
17 October 2026Amazon’s honeypots (decoy systems whose job is to record attacks) see a first exploit attempt, four days before the public disclosure. Amazon has said it is unclear how that actor already had the information.
20 October, about 15:00 UTCCVE numbers circulate with a wrong release time and a wrong score of 10.0, without the technical detail.
20 October, eveningPHP posts an advance notice and pulls the release forward from 22 October to 21 October at 14:00 UTC. A proof-of-concept video from Calif goes public. The PHP Foundation described that publication as a mistake. Copies move onto hacking forums.
21 October, early hoursWorking exploit claims are already being tried. Cloudflare’s CTO says early attacks are showing up, and Cloudflare pushes firewall rules, including to free plans.
21 October, 14:00 UTCFixes ship: PHP 8.5.12, 8.4.27, 8.3.36, and 8.2.35. Minimal source patches are published for people who build 7.4, 8.0, or 8.1 themselves. Those branches get no official release.

Calif researcher Ryan Austin told the BBC it was “the most serious vulnerability I’ve ever found”.
The AI part is real and easy to oversell. Research groups used AI assistance to turn a half-seen memory bug into a demonstrated takeover. OpenAI’s public comment on the episode was the other half of the same fact: the same class of tools helps attackers turn a patch into a working exploit quickly, because a patch is also a map. Finding got faster. Abuse got faster. The operational consequence is boring. The gap between “a CVE number leaked” and “someone is knocking” was hours. In Amazon’s honeypot data, knocking may have started days before the public even had the number.

What “millions of attacks” does not mean

Cloudflare’s CEO, Matthew Prince, posted the count every headline used. Across Cloudflare: thousands of exploit attempts in the 10 hours before the announcement, tens of thousands within 45 minutes after it, hundreds of thousands within two hours, and millions after that. Attackers were already rewriting requests to slip past firewall rules.

Amazon later called PHP2Shell “broadly exploited in the wild”. watchTowr said it saw exploitation in honeypots, and also that most of the exploit code going around does not achieve code execution. A lot of it probes, or it crashes the target. VulnCheck described at least one web-shell attempt that failed. A web shell (a secret page an attacker adds, so they can come back and type commands) is the usual sign that someone has moved in.
As of Blackout Map’s update at 22:00 UTC on 23 October, no public source had confirmed a completed break-in, and CISA had not put the two CVEs on its Known Exploited Vulnerabilities catalogue (the list CISA keeps of bugs it has actually seen used). CISA’s 21 October note said it had not observed exploitation at publication. Its 23 October update added a detection rule and told operators again to patch or leave the public internet. That bulletin did not announce a confirmed intrusion.
Hold both facts. The scanning is real, huge, and started before the patch. “Millions of attempts” is not the sentence “millions of sites were taken over”. The attempts are why you hurry. The gap is why you do not forward a screenshot that claims a bank was emptied by PHP on Tuesday.
The other reason the numbers fight each other is that counters measure different things:

Who countedWhat they countedFigure
Censys, 21 OctoberInternet-facing hosts that show a PHP version. Of 1.58 million that showed one, about 1.57 million were not on a fixed release yet.2.58 million PHP hosts seen
VulnCheckInternet-facing PHP hosts, including at least 1 million on versions that no longer get official updatesMore than 2.6 million
Palo Alto Unit 42, via NextgovInternet-exposed instances it judged potentially vulnerable. An instance (one copy of the software) is not a host (one machine). One machine can run many copies.More than 22.6 million

A scanner only sees what a server is willing to announce. None of these figures is “the number of hacked sites”.

The outages were mostly a choice

PHP2Shell did not knock the web over. Operators pulled sites down so they would not be reachable while they patched. That is the responsible version of an outage. It is still an outage if you needed the page.
Reported, with the outlet attached: Finnish government web services, via Valtori. Dutch sites including parliament, the national cyber centre, Overheid.nl, the Port of Rotterdam, hospitals, and political parties. French prefecture sites and, per the BBC, some Orange telecom services. German government IT sites, described by the operator as preventive. Belgian foreign-ministry sites. Wikimedia systems, as a precaution. The UK government told the BBC that some limited services might go offline, with 32 sites taken down as a precaution. Edinburgh council, and some BBC pages. Local Japanese media, cited by the BBC, reported that SoftBank temporarily suspended emergency earthquake and tsunami alerts. 4chan went read-only while it waited on the update. None of that is a claim that those organisations were breached.

What you should do

If you only browse. There is nothing to install. Your exposure is indirect. A site you use can be compromised later if its operator never patches, and then your account on that site is the prize. You cannot reliably read their PHP version from the outside. A version string in a footer can be a lie, and many sites hide it.
If you run WordPress, Drupal, Joomla, Laravel, Magento, phpBB, or a custom PHP app. Updating the app, the theme, or the plugins is not this fix. The bug is underneath them. Ask the host, in writing: which PHP version is this site on right now, and did you restart every PHP worker after the upgrade?

Branch you are onInstall at leastOfficial package?
8.58.5.12Yes
8.48.4.27Yes
8.38.3.36Yes
8.28.2.35Yes. PHP News noted this branch’s security support ending 31 December 2026. Do not treat 8.2 as a five-year home.
8.1, 8.0, 7.4No official release. Use your Linux distribution’s backport, the PHP project’s minimal source patches, or move to a supported branch.No
7.3 and olderMove off. There is no grown-up patch path.No

Restart is not a courtesy. Workers keep the old program in memory until they are restarted. On a container host, restarting a container built from an old image brings the old PHP back. Rebuild the image, then restart. Shared-hosting customers often cannot do this themselves. The email to the host is the task.
If you cannot patch today. The NSA’s 21 October advisory says take the system offline until it is fully mitigated. CISA says the same for anyone who cannot update immediately, and for anyone still on PHP 8.1 or older. Offline means not reachable from the public internet. It does not mean “we added a plugin”.
If the machine has been on the internet since 17 October. Patching stops the next attempt. It does not evict someone who already got in. As you upgrade, look for new admin users, PHP files you did not create, and scheduled tasks you did not add. CISA published a SIGMA detection rule on 23 October for teams that already collect logs. SIGMA (a shared format for describing suspicious log lines, which each security product translates into its own query language) is a hint list, not a guarantee. If you have no logs, say that out loud to whoever investigates. A missing dashboard is not the same as a clean server.

What is not a fix

You will see these settings named. They are not the fix, even the ones the PHP project discussed as partial blocks on a known path:

  • Setting memory_limit to unlimited.
  • Shrinking post_max_size, the cap on how large an incoming form body may be.
  • Turning off session.upload_progress.enabled.
  • Turning off fatal_error_backtraces on PHP 8.5.
    PHP News reported on 23 October that the PHP team suggested leaving upload-progress off until a follow-up release, because of a rarer related path tracked as CVE-2026-115560. Use that as a seatbelt while you drive to the patch. Do not announce “we are mitigated” because an ini file changed. An ini file (PHP’s configuration text) is not a new version of PHP.
    Do not set operating-system memory limits of the RLIMIT_AS or RLIMIT_DATA kind as a clever substitute. The advisory warns that those can hit the vulnerable path.

The part that stays true after the headlines leave

Three things, in the order they matter.
First, the long tail. Official packages cover four branches. W3Techs on 25 October says more than a third of PHP sites are on version 7 or 5, before you count 8.0 and 8.1 hiding inside “version 8”. Those sites do not get a normal update button. They get a migration, a vendor backport, or a decision to stay exposed. The patch on 21 October was the easy half, and only for people already on a supported branch.
Second, the clock changed in both directions. AI assistance helped researchers finish a bug a human had half-seen in 2024, after the fix had stalled. The same class of tools shortens the time from patch to exploit. You do not get a quiet week.
Third, a score is not a census of damage. A 9.2, millions of attempts, about 1.57 million unpatched version strings on day one, and no publicly confirmed mass compromise can all be true on the same weekend. The useful response is to patch, restart, and read the logs backward. The useless responses are “the whole internet is on fire” and “Cloudflare blocked it, so next quarter is fine”.

One sentence to keep: PHP2Shell is a pair of bugs in the engine under the website, fixed on 21 October 2026 in 8.5.12, 8.4.27, 8.3.36, and 8.2.35, and a WordPress update does not install those.

Common questions about PHP2Shell

What is PHP2Shell?

PHP2Shell is the nickname for two memory-safety bugs in PHP itself, CVE-2026-109618 and CVE-2026-109619. They were fixed on 21 October 2026 in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35.

Does updating WordPress fix PHP2Shell?

No. Updating the app, the theme or the plugins is not this fix. The bug is in PHP underneath them, so the PHP version has to change and every PHP worker has to restart.

I only browse websites. Do I need to do anything?

There is nothing to install. Your exposure is indirect: a site you use can be compromised later if its operator never patches.

Is turning off session upload progress enough?

No. It is a seatbelt while you get to the patch, not the fix. The packages from 21 October are the fix.

Leave a comment