A newly disclosed flaw in PHP’s HTTP stream wrapper (CVE-2026-12184) lets a remote server crash the PHP process that connects to it just by presenting a broken TLS configuration — an expired certificate or a hostname that doesn’t match. When PHP is running under PHP-FPM, that crash can take down the entire worker pool and cause a full outage. No special payload, no authentication, and no complex chain is required, which makes it trivially repeatable against any site that makes outbound HTTPS calls. It was disclosed and patched via official PHP security advisories on July 6, 2026. A companion memory-corruption bug in the OpenSSL extension (CVE-2026-14355) was fixed in the same release cycle.

What the Vulnerability Is

The bug lives in php_stream_url_wrap_http_ex, the function that handles HTTP(S) requests made through PHP stream wrappers (the machinery behind file_get_contents('https://…'), fopen, SOAP, and many HTTP client libraries).

When PHP opens an outbound HTTPS connection, it negotiates TLS via php_stream_xport_crypto_setup / php_stream_xport_crypto_enable. If that negotiation fails — for example because the remote certificate is expired or the peer name doesn’t validate — the stream resource is correctly closed and reset to NULL. The problem is a later cleanup routine that assumes the stream is still valid and unconditionally tries to reset the peer name on it. Operating on that freed/NULL stream produces a use-after-free–style condition that crashes the process.

Because the trigger is simply “the server on the other end has bad TLS,” an attacker only needs to control (or impersonate) a host that your PHP application connects to. Per PHP’s advisory GHSA-mhmq-mmqj-2v39, exploitation does not require specially crafted code. The issue was found by researcher ndossche using hybrid static/dynamic analysis, and fixed in pull request #21031.

Why It Matters

  • One request can nuke the whole pool. Under PHP-FPM, a single crash can terminate all workers in the pool, causing a complete service outage — not just a failed request. Repeated triggers mean sustained downtime.
  • No auth, low complexity. The condition is remotely triggerable by any server your code talks to. There’s no login and no exotic payload.
  • Huge attack surface. Modern PHP apps constantly make outbound HTTPS calls: webhooks, payment gateways, REST/GraphQL APIs, RSS/feed fetchers, oEmbed/link previews, SSO/OAuth callbacks, wp_remote_get() in WordPress, Composer, and SOAP clients. Any of those endpoints presenting invalid TLS can knock the site over.
  • Also reachable via SSRF-style features. If your app fetches a user-supplied URL (image proxy, “import from URL,” avatar fetch), an attacker can point it at a host they control with a deliberately broken cert.

Am I Affected?

You are exposed if all of the following are true:

  • You run PHP older than 8.3.32, 8.4.21, or 8.5.6 on the branch you’re using.
  • Your application (or a plugin/library it loads) makes outbound HTTPS/TLS connections through PHP streams — which is nearly universal for WordPress and most CMS/e-commerce stacks.
  • You serve requests via PHP-FPM (standard on NGINX and modern Apache setups), where a crash cascades across the worker pool.

Check your running version:

php -v
php-fpm -v      # or php-fpm8.3 -v, etc.

Note that the branch you’re on matters: 8.2 is not listed among the affected branches for CVE-2026-12184 in the advisory, but 8.2 users should still read the CVE-2026-14355 note below.

What to Do About It: Step-by-Step

Step 1: Patch PHP — this is the only real fix

No workarounds are documented. Upgrade to:

  • PHP 8.5.6 or later, or
  • PHP 8.4.21 or later, or
  • PHP 8.3.32 or later.

Step 2: On a distro package (Debian/Ubuntu/RHEL/Alma/Rocky)

# Debian / Ubuntu
sudo apt update && sudo apt upgrade php8.3 php8.3-fpm
# RHEL / AlmaLinux / Rocky (Remi or vendor stream)
sudo dnf update php php-fpm

Distributions frequently backport the fix to their packaged version, so a patched 8.3.x from your vendor is fine even if the version string differs — confirm the changelog references CVE-2026-12184.

Step 3: On cPanel/WHM (EasyApache 4)

Update via WHM → EasyApache 4 or yum update ea-php83 ea-php84, then confirm each installed PHP version.

Step 4: On Plesk

Tools & Settings → Updates → Add/Remove Components, or run the Plesk installer to pull the updated PHP builds; then reassign domains to the patched handler.

Step 5: Restart PHP-FPM after upgrading

So workers load the new binary:

sudo systemctl restart php8.3-fpm

Step 6: Also pick up CVE-2026-14355 (OpenSSL extension)

This moderate-severity heap buffer overflow in openssl_encrypt() with the AES-WRAP-PAD algorithm (improper RFC 5649 padding buffer sizing) can corrupt the Zend heap and cause later crashes. It is fixed in PHP 8.2.32, 8.3.32, 8.4.23, and 8.5.8 (advisory GHSA-7jrw-539f-x6vr). If you’re upgrading anyway, target a build that includes both fixes.

Step 7: Add monitoring as a stopgap and detection aid

Watch for abnormal PHP-FPM worker crashes / rapid respawns:

journalctl -u php8.3-fpm -f | grep -Ei 'SIGSEGV|exited on signal|restart'

Repeated segfaults tied to outbound requests can indicate exploitation attempts.

Step 8: Harden outbound fetches where you can

Validate and allowlist user-supplied URLs, and prefer libraries/timeouts that fail gracefully — but treat this as defense-in-depth, not a substitute for patching.

Quick-Win Checklist

  • Run php -v and php-fpm -v on every PHP version installed.
  • Upgrade to PHP 8.3.32 / 8.4.21 / 8.5.6 (or later) on the affected branch.
  • Confirm the CVE-2026-14355 OpenSSL fix is included (8.2.32 / 8.3.32 / 8.4.23 / 8.5.8).
  • Restart PHP-FPM and re-verify the running version.
  • On cPanel/Plesk, update every PHP handler, not just the default.
  • Add a watch for PHP-FPM segfault/restart storms.
  • Audit any “fetch from URL” features for SSRF-style abuse.

Sources