All insights
Engineering··8 min read

PHP2Shell: Critical PHP Vulnerabilities (CVE-2026-109618, CVE-2026-109619) — What Founders Should Do Now

PHP2Shell is two CVSS 9.2 RCE flaws (CVE-2026-109618, CVE-2026-109619) in PHP itself. Who is affected, fixed versions, and when to call engineers.

PHP2Shell: Critical PHP Vulnerabilities (CVE-2026-109618, CVE-2026-109619) — What Founders Should Do Now

On 21 October 2026 the PHP project shipped emergency security releases for two critical remote code execution (RCE) vulnerabilities, tracked as CVE-2026-109618 and CVE-2026-109619 and referred to collectively as PHP2Shell. Both score 9.2 on CVSS. They live in PHP’s core request handling, not in WordPress plugins, Laravel packages or your application code.

That matters for founders: a site can have clean app code and still be exploitable if the server runs a vulnerable PHP build. Attackers do not need a login. In the highest-risk setups, a single unauthenticated HTTP request can trigger the bug before your framework boots.

This article explains what PHP2Shell is, who is affected, which versions fix it, and a practical checklist you can hand to whoever manages your hosting.

What PHP2Shell is (in plain language)

PHP2Shell is two separate bugs that share a theme: PHP can leave memory or global state in a bad shape when a request ends abnormally, and a follow-up request—or cleanup code—can turn that into code execution or memory disclosure.

CVE-2026-109618 (OOM corruption) — When PHP hits its memory limit during request handling (for example while parsing a large multipart upload), it can abort via longjmp() while internal upload structures are only half-built. Cleanup then treats invalid pointers as real and frees attacker-influenced memory, which can lead to RCE as the web-server user.

CVE-2026-109619 (stale global state) — State tied to one request can outlive the request after a fatal error or similar early exit. The next request on the same worker process may reuse that stale state before PHP fully re-initialises, enabling heap use-after-free, memory leaks of other users’ data, and RCE.

Researchers and PHP’s security team have shown working exploit chains. Details leaked on 20 October, a day before the coordinated fix shipped, so treat unpatched internet-facing PHP as actively at risk, not theoretical.

Who is affected

You are in scope if any production system serves web requests through PHP, including:

SetupRisk notes
Apache + mod_phpPHP’s team calls this the highest risk; exploits can run before app code
PHP-FPM (Nginx, Apache proxy)Affected; workers reuse processes between requests (relevant to CVE-2026-109619)
php-cgi, FrankenPHP, LiteSpeedAffected when handling HTTP
Managed WordPress / Joomla / Drupal hostingYou depend on the host’s PHP version even if you never touch php.ini
Appliances & vendor UIsEmbedded PHP in firewalls, NAS admin panels, etc.—patch via vendor, not only OS PHP

PHP versions before the fixed releases below are vulnerable. PHP 8.1 and older no longer get routine updates from the PHP project; some Linux vendors backport fixes, and PHP published minimal source backports for 7.4–8.1 for teams that compile their own.

PHP2Shell is not “only WordPress.” It is any internet-facing PHP runtime on an unpatched version—including custom SaaS APIs you built in Laravel or Symfony.

Fixed versions — install these

Upgrade to the matching line for your branch:

BranchFixed release
PHP 8.58.5.12
PHP 8.48.4.27
PHP 8.38.3.36
PHP 8.28.2.35

On the server, confirm what you are running with php -v.

Also check CLI vs FPM: many hosts run one version on the command line and another for the website. Verify the FPM or mod_php version your site actually uses (hosting panel, phpinfo() in a protected staging slot, or your provider’s dashboard).

Distribution packages (Debian, Ubuntu, RHEL, etc.) often label builds differently from php.net tarballs—install the vendor security update for your OS and reboot PHP workers after upgrading.

Patch checklist for founders

Share this with your developer, agency or host. A box counts as done only when you have evidence—a version string, maintenance ticket, or staging test—not when someone says “we’re patched.”

1. Map what runs on PHP

  • List every internet-facing app on PHP: marketing site, product API, admin panels, and easy-to-forget subdomains
  • Record the PHP version for production and staging, for both CLI and the web SAPI (run php -v in each context)

2. Patch and restart

  • Install a fixed build: 8.5.12, 8.4.27, 8.3.36, or 8.2.35—or your Linux vendor’s LTS backport package
  • Restart PHP-FPM, Apache, FrankenPHP, or LiteSpeed workers so no pre-patch process keeps serving traffic
  • On managed WordPress or similar CMS hosting, confirm the host’s PHP runtime—not only core and plugin updates
  • On Docker or Kubernetes, rebuild images from an updated base and redeploy; don’t treat apt upgrade inside a running container as enough
  • For appliances or SaaS with embedded PHP, ask the vendor whether their product image includes the fix

3. Verify before you announce “done”

  • On staging, re-test file uploads, checkout flows, and payment webhooks
  • Review access and error logs for odd multipart POSTs, repeated fatals, or new unknown files under the web root

If three or more items are still open, pause non-essential releases until patching is verified.

Temporary mitigations (not a substitute for patching)

PHP’s security team is explicit: only upgrading fully fixes these bugs. If you cannot patch immediately—for example you are waiting on a host—you can reduce exposure on specific paths while you isolate or schedule maintenance.

Discuss these with someone who can edit php.ini, FPM pool config or Apache php_admin_value (not .user.ini alone):

  • Set session.upload_progress.enabled = Off (or 0) before request parsing, then restart all workers. This blocks confirmed session-related paths for CVE-2026-109619 but not every variant.
  • For CVE-2026-109618, PHP documents additional hardening: enforce memory_limit=-1 at the admin level where apps cannot override it, tighten post_max_size, and avoid misguided RLIMIT tricks that still trigger allocation failures.

WAF rules from CDN providers may block known exploit patterns but can never replace a patched runtime. Treat them as breathing room, not compliance.

Does this affect your MVP or AI-built product?

If you shipped on shared WordPress, cPanel PHP, or a Laravel API on a VPS, PHP2Shell is an infrastructure incident: your application source can be fine and the server still unsafe.

If you used AI builders for a PHP stack (or inherited a codebase without knowing the runtime), you may not know where PHP is configured. That is the same visibility gap we see in when an AI-built app needs a real engineering team: production risk sits below the UI.

When choosing who helps, use a partner that can show version evidence and rollback, not only plugin updates—see our checklist for choosing a development partner.

FAQ

Do I need to patch if I run Node or Next.js instead of PHP?

Only systems that execute PHP for HTTP requests need these PHP fixes. If PHP exists only on an old blog subdomain you forgot about, that subdomain still counts. Pure Node/Next deployments on Vercel without PHP are not affected by PHP2Shell itself—but Node.js and Next.js had their own October 2026 security releases; see Node.js, Next.js and Railway: three fixes founders need this week.

We are on PHP 8.1 or 7.x—what now?

Upgrade to a supported 8.2+ line with fixed packages if you can. If you rely on vendor LTS, install their backported security package. PHP 8.1 and below are end-of-life from the PHP project; staying there is a standing risk beyond this advisory.

Is disabling file uploads enough?

No. Uploads are a major demonstrated path for CVE-2026-109618, but the underlying flaw is in core cleanup and memory handling. Patching remains mandatory; upload limits are defense in depth.

Our host says they patched—how do we verify?

Don't rely on the version string alone. Many shared hosts run CloudLinux, which backports the fix without changing the version number, so a patched server can still show 8.3.35. Check the build date in phpinfo() (it should be 21 October 2026 or later) and ask your host to confirm in writing that the build includes the fix for CVE-2026-109618 and CVE-2026-109619. If you have SSH, check the package changelog: rpm -q --changelog alt-php83-common | grep CVE-2026-109618. Then remove any public phpinfo() page.

Sources

Official advisories and coordinated disclosure material:

If patching is blocked on a business-critical app, treat it like any other production rescue: isolate from the public internet until the runtime is verified, then schedule engineering time to harden config—not only to apply the one-line version bump.

Not sure if your stack is patched?

We audit production PHP apps—WordPress, Laravel, custom APIs—and quote fixes at a fixed price. Start with a free Finish Line Scan if the product was AI-built or inherited from another team.

Get a free scan