If you run a website built on PHP, there is a good chance you received an urgent security email this week. Maybe it came from your hosting company. Maybe it came from a client's IT team, or from a partner abroad. Ours came from several clients at once, in India, the UK and the US, all within a few hours of each other, and all saying roughly the same thing: "Check if you're affected. Patch immediately. Treat this as priority."
When the same warning lands in your inbox from three continents on the same day, it's worth paying attention. So here's what is actually going on, explained without the jargon, and exactly what you need to do about it.
The short version: on 21 October 2026, the PHP project released an emergency update to fix two critical security holes in PHP itself. Together, they've been nicknamed PHP2Shell. Attackers are already using them. If your website runs on an older PHP version, someone on the internet may be able to take control of your server without ever logging in.
The good news is that the fix is straightforward. Let's walk through it.
What is PHP2Shell, in plain English?
PHP is the programming language that powers a huge share of the web. WordPress runs on it. So do WooCommerce, Magento, Laravel, Drupal, and countless custom-built business sites and admin panels. Every time someone opens a page on one of these sites, PHP on the server does the work of building that page.
PHP2Shell is the name for two bugs, officially tracked as CVE-2026-109618 and CVE-2026-109619. Both are memory-handling mistakes deep inside the PHP engine.
Here's a simple way to picture them. Think of a busy restaurant kitchen where cooks share workstations. Normally, when a cook finishes an order, they clean their station before the next cook steps in. These bugs are like a cook who gets interrupted halfway through cleaning, and the next cook trusts whatever was left on the counter.
- CVE-2026-109618 happens when a request uses up all the memory PHP is allowed. PHP gets interrupted mid-task and leaves half-prepared data behind. Its clean-up routine then treats that broken data as if it were valid.
- CVE-2026-109619 happens when a PHP worker handles one visitor's request and then moves on to the next. Some leftover data from the first request survives, even though the memory behind it has already been freed. The next request picks it up and uses it.
On their own, those sound like stability bugs. The problem is that a skilled attacker can carefully craft a web request that deliberately triggers these situations. By shaping what gets left behind, they can trick PHP into running code of their choosing. That's what "remote code execution" means: a stranger on the internet gets to run commands on your server.
The name says it all. PHP to shell: from a web request straight to a command line on your machine.
Why this one is genuinely serious
Security advisories come out every week, and most of them don't deserve panic. This one is different, for four reasons.
1. No login required. Many vulnerabilities need an attacker to already have an account, or to trick an admin into clicking something. PHP2Shell needs neither. PHP processes the malicious request before your application code even gets a chance to look at it. Your login page, your admin password, your two-factor authentication: none of it stands in the way.
2. Your code doesn't matter. You could have written the cleanest, most secure Laravel app in the world, and it would still be exposed. The flaw sits in PHP itself, underneath your site. That's why every agency and hosting company sent out warnings at the same time. It affects everyone running PHP, regardless of framework.
3. It goes back years. Researchers say the bugs exist in every unpatched PHP version going back to PHP 5.4, released in 2012. More on that history below. Both common ways of running PHP on a web server are affected: Apache's mod_php and PHP-FPM.
4. Attackers moved first. This is the part that should get your attention. Details of the flaws leaked on 20 October, a day before the official fix. Cloudflare reported attacks on the morning of 21 October, hours before PHP released the patched versions. Amazon's threat intelligence team says its honeypots caught an exploitation attempt as early as 17 October. Automated scanners hunting for vulnerable servers appeared within hours of the announcement.
Both bugs are rated 9.2 out of 10 on the CVSS severity scale. In practice, that means "drop what you're doing."
A bug hiding in plain sight since 2012
The most remarkable part of this story is how long these flaws went unnoticed. The vulnerable code traces back to PHP 5.4, released in 2012. That means almost every PHP website built in the last 14 years has been sitting on top of it.
And it wasn't entirely unknown. Back in 2004, security researcher Stefan Esser warned that PHP's memory-limit shutdown could strike in places where an interruption is unsafe. That's essentially the same weakness PHP2Shell exploits, described 22 years earlier.
The specific out-of-memory problem behind one of the bugs was spotted in 2020, and spotted again by a PHP core developer during an audit in 2024. Both times, it stayed unfixed. Nobody had shown it could actually be turned into an attack, and the team couldn't agree on how to fix it, so it never made it to the top of the list. It's worth remembering that the PHP Foundation, which looks after a language running a huge share of the internet, has only 13 full- and part-time staff.
How AI finally cracked it open
What changed in 2026 was artificial intelligence.
At the end of July, Ryan Austin, a researcher at the security firm Calif, began auditing how PHP behaves when it runs out of memory. Working with OpenAI's GPT-5.6 Sol model as part of OpenAI's "Patch the Planet" initiative, he used his own hypothesis to steer the AI's search for related failure paths. On 1 August, he had his first finding. By 11 August, Calif had shown the old memory bug could be turned into full remote code execution and reported it to PHP. OpenAI independently reported the same root cause that day.
A week later, a separate team at Wiz, the cloud security company owned by Google, found the same class of bugs on its own. Its researchers used Google's Gemini 4 Argon, GPT-5.6 Sol and their in-house tool Wiz Atlas. They confirmed working attacks against Drupal and WordPress within two days and reported to PHP on 24 August.
It's important to be precise about AI's role. Humans led the research and PHP's own maintainers wrote the fixes. But the researchers say the hardest part, turning a crash into a working attack across many PHP versions and memory layouts, would have taken people months by hand. The AI models compressed that into weeks. Wiz has compared the episode to Heartbleed, the 2014 flaw that affected encryption on roughly two-thirds of the web.
That cuts both ways. The same tools that helped defenders find PHP2Shell first are available to attackers too. The gap between a bug being disclosed and being exploited is shrinking fast, which is exactly why patching quickly matters more than ever.
| When | What happened |
|---|---|
| 2004 | Stefan Esser warns about unsafe memory-limit interruptions in PHP |
| March 2012 | PHP 5.4 ships with the code that would later become vulnerable |
| 2020 | The out-of-memory flaw is first noticed, but left unfixed |
| 2024 | A PHP core developer rediscovers it in an audit; still unfixed |
| 30 Jul–1 Aug 2026 | Calif starts its AI-assisted audit and makes its first finding |
| 11 Aug 2026 | Calif and OpenAI report the remote code execution path to PHP |
| 19–24 Aug 2026 | Wiz independently finds the bugs and reports them to PHP |
| 17 Oct 2026 | Amazon's honeypots catch the first exploitation attempt |
| 20 Oct 2026 | Details leak publicly |
| 21 Oct 2026 | PHP releases the fixed versions and the flaws are disclosed |
Are you affected? A two-minute check
If your site runs PHP and you haven't updated since 21 October 2026, assume yes until you've confirmed otherwise.
The quickest way to check is to look at the PHP version your website is actually using. That last word matters. Many servers have several PHP versions installed, and the one you see in a terminal isn't always the one serving your pages.
Option 1: in your hosting panel. In cPanel, open MultiPHP Manager or Select PHP Version and note the version listed for each domain.
Option 2: a phpinfo page. Create a file called something unguessable, like check-8f3k2.php, containing a single line: <?php phpinfo();. Upload it to your site, open it in a browser, and the version is printed right at the top. Delete the file immediately afterwards. A public phpinfo page tells attackers exactly what you're running, which is the last thing you want this week.
Option 3: on the server. Run php -v. For sites served by PHP-FPM, check the FPM binary too, for example php-fpm8.3 -v.
Then compare your version against this table:
| Your PHP branch | Safe version (or newer) |
|---|---|
| PHP 8.5 | 8.5.12 |
| PHP 8.4 | 8.4.27 |
| PHP 8.3 | 8.3.36 |
| PHP 8.2 | 8.2.35 |
| PHP 8.1, 8.0, 7.x or older | No fix. Move to a supported branch |
One detail catches people out: the number has to match exactly. We checked one of our own servers and found PHP 8.3.35, one point short of the fix. It looked recent. It was still vulnerable.
If you're on PHP 7.x, 8.0 or 8.1, those versions no longer receive security updates at all. This is the push to finally upgrade. And note that PHP 8.2 itself reaches end of life on 31 December 2026, so if you're moving anyway, 8.3 or 8.4 is the better target.
How to patch it: the real fix
There's only one proper fix: update PHP to a patched version and restart it. The PHP team has been clear that updating is the only safe choice. Everything else is a temporary bandage.
How you do that depends on where your site lives.
If you manage your own server (VPS or dedicated)
On Ubuntu or Debian, update your PHP packages through the package manager:
sudo apt update
sudo apt install --only-upgrade php8.3*Replace 8.3 with your version. On AlmaLinux, Rocky or CentOS, use sudo dnf update php* instead.
Then comes the step people forget: restart PHP. A running PHP worker keeps using the old, vulnerable code in memory until it's restarted. Updating the files on disk isn't enough.
sudo systemctl restart php8.3-fpm
sudo systemctl restart apache2 # if you use mod_phpAfterwards, check the version again through the website, not just the terminal.
If you're on cPanel with CloudLinux
Many Indian and international hosts run cPanel on CloudLinux, which provides its own PHP builds called alt-php. You can usually spot this in a phpinfo page by paths containing /opt/alt/php83/ or similar.
If you have root or WHM access:
yum update alt-php*Then restart the web server and PHP handlers from WHM. Make sure you update every alt-php version installed on the server, not just the one your main site uses. Other accounts on the same machine may be using a different version.
If you're on shared hosting
You can't patch PHP yourself, and that's fine. Your host is responsible for it. Send them a short ticket:
Please confirm our server has been updated to a PHP release that fixes CVE-2026-109618 and CVE-2026-109619 (8.2.35, 8.3.36, 8.4.27 or 8.5.12), and that PHP has been restarted.
Once they confirm, open your PHP version selector and make sure your domain is set to a patched version. If your site is still on PHP 7.4 or 8.0 for compatibility reasons, now is the time to test it on 8.3 and switch.
If you use Docker
Rebuild your images from the updated official PHP base image, for example php:8.3-fpm, and redeploy. Restarting an old container won't help; the vulnerable PHP is baked into the image.
Can't patch today? Buy yourself some time
Sometimes you're waiting on a host, or an upgrade needs testing first. In that case, there are a couple of settings that reduce the risk in the meantime. Be clear about what they are, though: partial shields, not fixes.
Turn off session upload progress. Add this line to your php.ini (or in cPanel, through the MultiPHP INI Editor):
session.upload_progress.enabled = 0Then restart PHP. This closes the attack route that researchers demonstrated for CVE-2026-109619. Very few sites actually rely on this feature, so it rarely breaks anything. But it does nothing at all against CVE-2026-109618.
On PHP 8.5 only, also add:
fatal_error_backtraces = 0You'll see some guides suggest setting memory_limit = -1 to block the out-of-memory trick behind CVE-2026-109618. We'd be cautious here. Removing the memory limit means a single heavy request can eat all the memory on your server and take it down. That trades one risk for another.
To confirm a setting has taken effect, check it in a phpinfo page served through your website. The value should show Off. And again, delete that page as soon as you've looked.
Patched? Now check whether someone got in first
Because attacks started before the fix was public, patching closes the door but doesn't tell you whether someone already walked through it. If your server was running a vulnerable PHP version for a few days, spend twenty minutes looking around.
Read your access logs. Look for unusually large POST requests (form submissions), especially to index.php, from IP addresses you don't recognise. Early scanning tools have been identifying themselves with user agents containing php2shell, such as php2shell-scan or php2shell-poc. Attackers can change these easily, so don't treat a clean search as proof, but a hit is a clear red flag.
Read your error logs. A cluster of "Allowed memory size exhausted" errors around 17 to 22 October, particularly ones that happen right at the start of a request, deserves a closer look.
Look for files that shouldn't be there. Attackers who get in typically leave a "webshell", a small PHP file that lets them come back later. Check upload folders, cache directories and the site root for recently modified PHP files:
find /home/*/public_html -name "*.php" -mtime -7In a WordPress site, PHP files inside wp-content/uploads are almost always suspicious.
Watch for odd processes. Unexpected shell commands, cryptocurrency miners or unfamiliar processes running under your web server's user are a strong sign of compromise.
If you find something, don't just delete the file and move on. Assume database passwords, API keys and other secrets on that server may have been read, because researchers have also shown these bugs can leak memory contents. Rotate those credentials, restore from a known-clean backup if needed, and get a professional to review the server.
And the GitLab flaw that arrived the same day
Many of the advisories going around bundle PHP2Shell with a second warning, about GitLab. It's a completely separate problem that happened to land on the same date, 21 October 2026.
The GitLab bug, CVE-2026-110264, is an integer overflow in the regular expression engine GitLab uses. Under certain conditions, it lets an attacker run code on a GitLab server without logging in. It's rated 10.0, the maximum possible score, and it affects every GitLab version going back to 7.0, released in 2014. There's no workaround setting; upgrading is the only fix.
Whether you need to act depends on how you use GitLab:
- If you just push code to gitlab.com, you don't need to do anything. GitLab has already patched its own servers.
- If your company runs its own GitLab server (self-managed Community or Enterprise Edition), upgrade now to the fixed release for your branch: 19.5.1, 19.4.3, 19.3.6, 19.2.9, 19.1.9, 19.0.10 or 18.11.13.
One trap worth knowing: GitLab released a different critical patch just nine days earlier, on 12 October. If you upgraded to 19.4.2 then, you're still exposed to this new flaw. You need 19.4.3.
Your quick checklist
If you skimmed everything above, this is what to do today:
- Check the PHP version your website actually runs, for every site and server you manage.
- Update to PHP 8.2.35, 8.3.36, 8.4.27 or 8.5.12 (or newer), or ask your host to.
- Restart PHP-FPM or Apache so the update actually takes effect.
- Move any site still on PHP 7.x, 8.0 or 8.1 to a supported version.
- If you can't patch today, set
session.upload_progress.enabled = 0as a stopgap. - Delete any public phpinfo pages.
- Review logs and look for unfamiliar PHP files dated from 17 October onwards.
- If you run your own GitLab server, upgrade it to the fixed release for your branch.
The bigger lesson
PHP2Shell is a reminder that keeping a website secure isn't a one-time job done at launch. The software underneath your site needs updating, often at short notice, and the window between a flaw being disclosed and attackers using it is now measured in hours, not weeks.
The businesses that came through this week calmly were the ones who knew exactly which servers they had, which PHP versions those servers ran, and who was responsible for updating them.
If you're not sure where your website stands, or you'd rather have someone handle the patching, log review and upgrade testing for you, the team at Nepras Technologies can help. Ask us for a free check and we'll look at your setup and tell you plainly what needs doing.
Sources
- PHP2Shell research (Sansec)
- PHP2Shell patched (Help Net Security)
- Detection and remediation (Datadog Security Labs)
- Attacks before the patch (Ellio)
- Exploitation indicators (VulnCheck)
- Fixed versions (Brandefense)
- Mitigation settings (Sevalla)
- GitLab Critical Patch Release 19.5.1
- GitLab CVE-2026-110264 fixed versions (Safeguard)
- PHP2Shell overview (Wikipedia)
- How the vulnerabilities were found (SecurityWeek)
- Discovery timeline (DEV Community)
- AI finds the flaw (CNN)
- The 2004 warning (Intruder)
Frequently Asked Questions
PHP2Shell is the name for two critical memory-handling bugs in the PHP engine, CVE-2026-109618 and CVE-2026-109619, fixed on 21 October 2026. A crafted web request can use them to run code on the server without logging in.
PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, or newer. PHP 8.1, 8.0 and 7.x receive no fix, so sites on those versions need to move to a supported branch.
Only once PHP has been restarted. Running PHP-FPM or Apache workers keep the old, vulnerable code in memory until they restart, so restart them and check the version through the website itself.
Set session.upload_progress.enabled = 0 in php.ini and restart PHP. It closes the demonstrated attack route for CVE-2026-109619 but does nothing against CVE-2026-109618, so it is a stopgap, not a fix.