Zenveus founder portrait
Zenveus founder portrait
Zenveus founder portrait
Zenveus founder portrait

Trusted by founders and incubator-backed teams

PHP2Shell: What to Check on Your PHP Servers Today

October 21, 2026 • 5 min read • Team Zenveus
Isometric illustration of a server unit with a cracked memory module leaking red fragments, and a blue patch panel moving in to seal it

Introduction

PHP shipped an out-of-cycle security release on October 21, 2026, for two critical bugs: CVE-2026-109618 and CVE-2026-109619, which researchers have dubbed PHP2Shell. PHP rates both 9.2 on CVSS v4.0, and its advisories describe unauthenticated remote code execution as the web server’s user (php.net). The fixed versions are 8.5.12, 8.4.27, 8.3.36 and 8.2.35.

If your product is a Next.js app on Vercel, this can look like someone else’s problem. It often isn’t. The marketing site may be WordPress on shared hosting, the API may be Laravel, and the billing tool or help desk may run PHP nobody on the team chose. Below: how to find those servers, patch them, limit exposure while your host catches up, and look for signs that someone already got in.

What you’ll learn

  1. What PHP2Shell is and which PHP versions fix it
  2. Where PHP hides in a stack that isn’t “a PHP app”
  3. How to confirm the version your web server actually runs
  4. How to patch on shared hosting, a VPS or containers
  5. Stopgaps while you wait, and signs you were already hit
  6. The cheaper leaks to close while you’re on the server

What is PHP2Shell, and which PHP versions fix it?

PHP2Shell is a pair of memory-safety bugs in how PHP sets up and tears down web requests. Both can lead to remote code execution without a login. PHP fixed them in 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released October 21, 2026; anything older on those branches is affected.

CVE-2026-109618 is in out-of-memory handling. If PHP runs out of memory while request data is only partly initialized, the shutdown code can read that half-built state as if it were valid (GHSA-w8hw-w9fx-j79w). CVE-2026-109619 is a use-after-free: a worker can keep global state that points into memory owned by an earlier request, and code that runs before the next request is set up can touch it (GHSA-6wmf-4rv5-p3rp).

How exposed you are depends on how PHP runs. The advisories confirm code execution on Apache with mod_php, and validated one path against PHP-FPM. They describe LiteSpeed (LSAPI) and FrankenPHP as likely or conditionally susceptible but not yet validated. That is a reason to patch everything, not a reason to wait on the setups that haven’t been proven yet.

PHP 8.1 and older get no project releases, though PHP links minimal backports for 7.4, 8.0 and 8.1 from its announcement. watchTowr’s FAQ says the flaws reach back to PHP 5 and that it observed exploitation in its honeypot network as of October 21. Tenable’s FAQ quotes Cloudflare’s CTO saying the company is seeing early attacks. As of this writing, CISA has not added either CVE to its Known Exploited Vulnerabilities catalog.

Does PHP2Shell affect you if your product isn’t written in PHP?

Probably, somewhere. Teams that build the product in Next.js, Lovable or Replit often still run PHP for the marketing site, a Laravel API, an internal admin tool, a hosting control panel or a vendor’s self-hosted software. Each of those is a separate server to check.

Before touching anything, write a short list: every place PHP runs, and who controls its version. A WordPress or Craft site on shared or managed hosting is the host’s to patch. A Laravel or Symfony API on a VPS is yours, or your Linux distribution’s. Anything in containers is only as current as its base image. Then add the things that are easy to forget: admin panels, billing dashboards, help desks, forums, self-hosted analytics, cPanel or Plesk, and appliances that bundle PHP.

How do you check which PHP version your site actually runs?

Check the PHP that answers web requests, not the one in your terminal. Running php -v over SSH shows the command-line build, and on many hosts the web server uses a different one. What you need is the web build’s version and when it was built.

The quickest signal is the response header. Many servers still send something like X-Powered-By: PHP/8.3.35, which you can see with curl -sI https://yoursite.com | grep -i powered. Most hosting panels also show the active version per site. If neither helps, upload a one-line file that prints PHP_VERSION and PHP_SAPI, give it a random name, open it once and delete it right away. Don’t leave a phpinfo() page online.

If PHP comes from your Linux distribution, the version string isn’t the whole story. Distributions may backport security fixes into packages that still carry an older-looking version, so check your vendor’s advisory and the package build date.

How do you patch PHP2Shell on shared hosting, a VPS or containers?

It depends on who controls the PHP binary. On shared hosting you wait for the host, so ask them for a date; Your host hasn’t patched PHP yet covers what to ask and what you can set meanwhile. On a VPS you install the security update and restart every PHP worker. In containers you rebuild on a patched base image and redeploy.

  • Shared or managed hosting: open a ticket asking when patched builds for CVE-2026-109618 and CVE-2026-109619 will be on your server. Switching PHP versions in the panel only helps if the version you switch to is already patched.
  • VPS or dedicated server: install your distribution’s update, then restart PHP-FPM, Apache or LiteSpeed so no worker keeps running the old code. Confirm the new build from the web side, not only the CLI.
  • Docker or Kubernetes: move the base image to a patched release, rebuild, and roll out every service built on it. Restarting a container on the old image changes nothing.
  • PaaS, SaaS and appliances: check the vendor’s status page or advisory, and keep their answer on file.

What can you do if a patched PHP build isn’t available yet?

Both advisories say updating is the only complete fix, but they list stopgaps that reduce exposure. The cheapest are turning off session upload progress, capping request size, and on PHP 8.5, disabling fatal error backtraces. Set them at the server level and keep pushing for the patch.

For CVE-2026-109619, set session.upload_progress.enabled=0 in php.ini, the FPM pool or the server configuration, then restart every worker. PHP’s announcement warns that ini_set() and .user.ini apply too late to help. The advisory suggests leaving the feature off even after patching if you don’t use it. On PHP 8.5, also set fatal_error_backtraces=0. If performance is not a concern, the advisory also suggests pm.max_requests=1 for PHP-FPM, which recycles each worker after a single request.

For CVE-2026-109618, lower post_max_size (PHP suggests 8M if you take no uploads, 32M if you do), keep upload_max_filesize below it, and limit request size, form fields, multipart parts and headers at the web server, proxy or WAF. The advisory also describes forcing memory_limit=-1 and calls that incomplete; on shared hosting, talk to your host before changing it.

And if an internal PHP tool doesn’t need to be on the internet, put it behind a VPN or an IP allowlist until it’s patched.

How do you check whether a server was already compromised?

Look for what an attacker usually leaves behind: PHP files where none belong, changed core files, new admin accounts, new scheduled jobs, and PHP launching shells. Clean results don’t prove a server is clean, but they rule out the most common follow-up steps after a break-in.

  • On WordPress, find wp-content/uploads -name "*.php*" should return almost nothing. Read anything unexpected, especially files that contain eval(base64_decode( or act directly on $_POST.
  • Compare files changed since October 17 in the web root, theme and plugin folders against deploys and updates you know about.
  • Run wp core verify-checksums and wp plugin verify-checksums --all to compare WordPress files with the official releases.
  • Review administrator accounts, SSH keys, cron entries and scheduled tasks for anything new.
  • Treat PHP-FPM, Apache or LiteSpeed starting sh, bash, curl or wget as a strong warning sign. A run of out-of-memory fatals in the error log is worth reading too, given how CVE-2026-109618 works.

For a WordPress site, the full walkthrough is in How to tell if your WordPress site was hacked. If something turns up, take the server off the internet, copy the web server and PHP logs before they rotate, and change every secret that server could read.

What else should you fix while you’re on the server?

You’re already logged in, so close the cheap leaks next to the patch: backups and database dumps in the public folder, a server that announces its PHP version, default admin credentials, and secrets sitting in code. Each takes minutes.

Start with backups. Search the public folder for .zip, .tar.gz, .sql, .sql.gz, .wpress and .env files, then try to download them from outside the network. Migration and backup plugins are a common source of full-site archives left in the web root. Move anything you find somewhere private; Backup or .env file publicly downloadable from your website covers the server rule and what to rotate.

Then check where your secrets live. If a database connection string ever shipped to the browser, treat it as public and rotate it; our Fix Library walks through this for Next.js in Next.js database URL exposed in the browser: what to do now. AI and payment keys in frontend bundles get the same treatment, covered in Gemini API key exposed in frontend code: how to secure AI calls. Generated apps also tend to ship with a placeholder admin login or a hard-coded session secret, which would turn any foothold into full control; Replit app has a default admin password or session secret: what to fix first shows what to change first.

Once you’re patched, set expose_php = Off so the server stops advertising its version (see Server exposes its PHP version in the X-Powered-By header). More symptom-by-symptom guides are in the Zenveus Fix Library.

Why does an emergency PHP patch become a production readiness question?

Installing the patch takes minutes. The slow part is everything around it: knowing every place PHP runs, being able to ship an update the same day, keeping secrets out of reach, and having something that would tell you about a break-in. Those habits decide how bad a week like this gets.

The Zenveus Production Readiness Standard turns them into nine scored checks, and the free production readiness self-check runs them against your own repository. If you want an engineer to own the answer, the 48-Hour Verdict puts a named senior engineer on your codebase for $299. They trace authorization, data boundaries, payments and webhooks, failure handling and deployment, then sign a written decision against the Standard with evidence and next steps. If the question is specifically who can reach your data, the Security & Data Isolation Audit is a fixed-scope review of authentication, authorization, tenant isolation, secrets, APIs, webhooks, dependencies and storage permissions, typically completed in three to five days. For a working AI-built product that now has to survive real users and security reviews, AI Prototype Hardening covers both the audit and the fixes.

For every incident we are tracking that affects AI-built apps, with what to do for each, see Security alerts for AI-built apps.

NEXT STEP

Find the gaps before the next emergency patch does

A named senior engineer reviews your codebase against the Production Readiness Standard and signs a written verdict in 48 hours: what is safe, what is exposed, and what to fix first.

Get the 48-Hour Verdict ($299)

Sources

Need an engineering partner, not just developers?

Zenveus works with founders as a technical leadership layer across validation, architecture, MVP, launch, and scale.

FAQs

Frequently Asked Questions

Which PHP versions fix PHP2Shell?

PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35, released October 21, 2026, fix both CVE-2026-109618 and CVE-2026-109619. PHP 8.1 and older get no project releases, though PHP links minimal backports for 7.4, 8.0 and 8.1. Distribution packages may carry the fix under an older version number, so check your vendor's advisory.

Is my site affected if it runs on LiteSpeed or PHP-FPM rather than Apache mod_php?

Treat it as affected. PHP's advisories confirm code execution on Apache with mod_php and validated one path against PHP-FPM. They describe LiteSpeed (LSAPI) and FrankenPHP as likely or conditionally susceptible but not yet validated. The fix is the same for all of them: run a patched build.

Can I fix PHP2Shell myself on shared hosting?

Not completely. On shared or managed hosting the provider controls the PHP binary, so they have to deploy a patched build. You can ask them for a date, switch PHP versions only if the target version is already patched, and apply stopgaps such as a lower post_max_size through your hosting panel.

Do the PHP2Shell mitigations make a server safe?

No. Both advisories say updating to a patched release is the only complete fix. Turning off session upload progress, capping request size and, on PHP 8.5, disabling fatal error backtraces reduce exposure until a patched build is running on every server that handles web requests.

How do I know if a server was compromised through PHP2Shell?

Look for PHP files in upload folders, unexpected changes to web root, theme or plugin files, new admin accounts, new cron jobs, and PHP processes starting shells or download tools, going back to at least October 17, when the first attempt was seen. On WordPress, verify core and plugin checksums. If you find anything, isolate the server, copy the logs and change every secret it could read.

Still have questions? Book a consultation.

Scroll to Top

Optional tracking stays off until you enable it. You can change your choice at any time.

Essential — always active
Security, requested features, and remembering these choices.

Read our cookie policy