PHP 8.5.11 SOAP: what I would change after CVE-2026-91765

PHP 8.5.11 SOAP: what I would change after CVE-2026-91765

PHP 8.5.11 shipped 24 Sep 2026 for CVE-2026-91765. I would run php -v, php-fpm -v, and php -m before I claim I am patched. This is a SoapServer DoS on ext-soap, not a Laravel-core CVE. Ubuntu 24.04 archive PHP is still not that tag.

· 9 min read #php #security #php-8-5 #soap #cve

 CVE-2026-91765 is a PHP tag, not Laravel core

Caption: php -v first. Then the FPM binary Nginx actually uses. Then php -m. If soap is missing and the app has no SoapServer, stop. Illuminate does not ship this CVE.

I did not post a nested SOAP document at anything tonight. I opened an Ubuntu 24.04 VPS that still runs a Laravel 13 app and ran php -v. PHP 8.5.11 is a security release dated 24 September 2026. php.announce #506 is 24 Sep 2026 11:57:48 UTC. php.watch dates the same tag 2026 Sep 24 and still lists it as latest on 2 Oct 2026. I will not invent an 8.5.12.

The failure this week is famous for two shapes. Either CLI already prints 8.5.11 and the socket Nginx uses does not, or apt upgrade on stock Ubuntu 24.04 stays on php8.3 8.3.6-0ubuntu0.24.04.11 from USN-8743-1 (10 Sep 2026) and I tell myself I am patched because a USN exists. This is a lab note. I did not write a remote exploit. I did not paste a payload.

What changed

php.net’s 8.5.11 announcement calls it a security release and tells every 8.5 user to upgrade. Same-day security tags, all 24 Sep 2026:

Branch Tag php.announce Note I would not skip
8.5 8.5.11 #506, 11:57 UTC Latest 8.5 I can cite on 2 Oct.
8.4 8.4.26 #508, 15:45 UTC Latest 8.4 on php.watch 8.4 releases.
8.3 8.3.35 #505, 10:58 UTC 8.3.34 was skipped (tag-creation mistake).
8.2 8.2.34 #507, 14:06 UTC Security window closes 31 Dec 2026.

What I will treat as locked:

  • CVE-2026-91765 / GHSA-rgrp-mwpx-f6rm. Published 24 Sep 2026. Package is ext-soap, not laravel/framework. cleanup_xml_node() walked the parsed SOAP document with no depth limit. The reachable path the advisory names is SoapServer::handle() → soap_xmlParseFile("php://input") → that cleanup. CVSS 7.5 (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H). Availability only. Tenable and OpenCVE date the CVE record 25 Sep 2026.
  • The fix is a depth budget, not a Laravel patch. The advisory’s remediation introduces SOAP_MAX_XML_DEPTH (2048), rewrites the cleanup and the WSDL search as iterative walks, and tracks SOAP_MAX_DECODE_DEPTH so href chains and cycles stop. Affected: 8.2. < 8.2.34*, 8.3. < 8.3.35*, 8.4. < 8.4.26*, 8.5. < 8.5.11*.
  • Same tags, sibling FPM advisory. GHSA-62xp-839h-2637 / CVE-2026-91768, also published 24 Sep 2026: listen.allowed_clients compared only the first 12 of 16 IPv6 bytes, so the ACL matched a /96 instead of an exact address. CVSS 6.5, adjacent. Unix sockets, IPv4-only pools, or an external firewall as the real boundary are not that bug.

What I will treat as rumor: Laravel core (there is no Illuminate CVE), a pasteable remote break-in (the lab is version + module + bump), Ubuntu 24.04 already shipping 8.3.35 (USN-8743-1 is 8.3.6, 10 Sep 2026), or PHP 8.6 as the fix. php.watch’s 8.6 index dates 8.6.0RC2 24 Sep 2026. That is a QA tag. GA is still 19 Nov 2026. SoapClient talking to a bank is not SoapServer::handle().

What I would change in a real Laravel/PHP app this week

Three edits. None of them is “rewrite the billing SOAP.”

1. Prove the binary Nginx uses. Then see soap.

php -v
php-fpm8.5 -v
# or: php-fpm8.4 -v / php-fpm8.3 -v — the pool in the vhost, not the one I wish I had
php -m | grep -i soap
rg "SoapServer" app/ routes/ config/

The error I actually expect on a box that “already upgraded” is the CLI/FPM split:

PHP 8.5.11 (cli) (built: Sep 24 2026)
# and, from the socket Nginx still owns:
PHP 8.5.10 (fpm-fcgi)

Or the honest miss:

# php -m | grep -i soap
# (empty)

If soap is absent and SoapServer is absent, CVE-2026-91765 does not apply. I would still bump FPM for CVE-2026-91768 if the pool listens on IPv6 TCP and I trusted listen.allowed_clients as a wall.

2. Install the tag I can cite. Reload FPM.

On Ubuntu 24.04 with ppa:ondrej/php, Launchpad already published the floors:

  • php8.5 8.5.11-1+ubuntu24.04.1+deb.sury.org+1, published 24 Sep 2026 (Noble)
  • php8.4 8.4.26-1+ubuntu24.04.1+deb.sury.org+1, published 24 Sep 2026
  • php8.3 8.3.35-1+ubuntu24.04.1+deb.sury.org+1, published 25 Sep 2026
  • php8.2 8.2.34-1+ubuntu24.04.1+deb.sury.org+1, published 24 Sep 2026
apt-cache policy php8.5-fpm
sudo apt update
sudo apt install --only-upgrade php8.5-cli php8.5-fpm php8.5-soap
sudo systemctl reload php8.5-fpm
php-fpm8.5 -v

reload is the step I skip when I am tired. OPcache will keep serving the old worker until that happens. I would not invent that stock Ubuntu php8.3 will land 8.3.35 this afternoon.

3. Stop constructing SoapServer on an unpatched binary.

The advisory’s path is SoapServer::handle(). If a leftover route still exposes one, I would gate it on the floor for this branch.

use SoapServer;

function phpSoapPatchFloorMet(): bool
{
    $id = PHP_VERSION_ID;

    return match (true) {
        $id >= 80500 => $id >= 80511,
        $id >= 80400 => $id >= 80426,
        $id >= 80300 => $id >= 80335,
        $id >= 80200 => $id >= 80234,
        default => false,
    };
}

// Before — the route constructed the server as soon as it was hit.
// $server = new SoapServer(storage_path('wsdl/legacy.wsdl'));
// $server->setClass(LegacyBillingService::class);
// $server->handle();

// After — refuse the endpoint until FPM is on a patched tag.
if (! extension_loaded('soap') || ! phpSoapPatchFloorMet()) {
    abort(503, 'SOAP endpoint disabled until FPM is on a patched PHP.');
}

$server = new SoapServer(storage_path('wsdl/legacy.wsdl'));
$server->setClass(LegacyBillingService::class);
$server->handle();

That 503 is a brake, not the patch. The patch is the PHP package. If I have no SoapServer in app/, I delete the gate and I still reload FPM.

What would bite on a self-hosted VPS

 Version check, soap module, then PPA vs distro PHP

Caption: rg SoapServer and php -m first. Distro apt on Ubuntu 24.04 is still 8.3.6. ondrej Noble already has the four patched tags. Reload the pool Nginx uses.

First bite: the socket, not php -v. I install php8.5-cli so Composer looks modern, and I leave Nginx on unix:/run/php/php8.3-fpm.sock or on an 8.5 pool I never reloaded. The advisory dies in the worker that parsed php://input. That worker is FPM.

Second bite: stock Ubuntu vs ondrej. Ubuntu 24.04 archive PHP is still 8.3.6-0ubuntu0.24.04.11. Ubuntu 26.04’s last cited USN package is php8.5 8.5.4-0ubuntu1.3 — also not 8.5.11. If the host will not let me add the PPA (or packages.sury.org on 26.04), I do not patch this by editing ext/soap in place.

Third bite: php8.5-soap is a separate package, and IPv6 TCP + listen.allowed_clients is the sibling only. After the bump I would run php-fpm8.5 -m | grep -i soap on the same binary as the socket. If the pool is already listen = /run/php/php8.5-fpm.sock, CVE-2026-91768 is not my bug. config.platform.php stays on the FPM I serve.

Eight days after the tag

 Advisory timeline from 24 Sep tags to this 2 Oct lab note

Caption: Four security tags and both GHSAs on 24 Sep 2026. CVE-2026-91765 dated 25 Sep. I am writing 2 Oct. php.watch still has 8.5.11 as latest 8.5. PHP 8.2 security ends 31 Dec 2026.

php.net supported versions (retrieved 2 Oct 2026): 8.5 active until 31 Dec 2027. 8.4 active until 31 Dec 2026. 8.2 security until 31 Dec 2026 — three months from this post. Honest target: Laravel 13 on PHP 8.5.11 FPM via ondrej, CLI and socket the same tag, Unix socket. I would not invent the next Thursday tag today.

Are you on this in production?

If FPM already prints 8.5.11 (or 8.4.26 / 8.3.35 / 8.2.34 on that branch) and you have no SoapServer, you are on the SOAP CVE the boring way: the binary is patched and the endpoint was never yours. If CLI says 8.5.11 and phpinfo() in the browser is still 8.5.10 — or the host will not give you that pool — you are not. Distro-only Ubuntu 24.04 on 8.3.6 is the third camp. Shared hosting with no PPA is the fourth. I did not flip a client cluster tonight. I want to know which of those you are in.

Did you hit the same wall?

I would get stuck on CLI 8.5.11 / FPM 8.5.10 after apt install, or on apt-cache policy php8.3 still showing 8.3.6 on a box that never added ondrej. Did you hit the same thing, or a different one — php -m empty for soap, a panel that will not reload the pool, listen = [::]:9000 plus an ACL you thought was exact? Tell me in the comments. I read them.

If the blocker is the VPS itself (PPA vs distro PHP, the wrong socket, a host that will not give you 8.5.11), I do this class of bump for a living: Hire for deploy.

References

Share:

Get new posts in your inbox

No spam. One short email per new article — practical PHP, Laravel, devops, and AI-assisted workflows.

Comments

Powered by GitHub Discussions via Giscus. A free GitHub account is required.