Back to Blog
PHP's Sep 24 Security Patch: Patch Before You Chase 8.6 RC
PHP shipped four security releases on Sep 24. If you run production PHP, patch to 8.2.34, 8.3.35, 8.4.26, or 8.5.11 before you worry about 8.6 RC2.
Back
Engineering
Table of contents
PHP's Sep 24 Security Patch: Patch Before You Chase 8.6 RC
PHP shipped four security releases on 24 Sep 2026. Versions 8.2.34, 8.3.35, 8.4.26, and 8.5.11 all landed the same day, and if you run production PHP, those version numbers are what you need to chase, not 8.6 RC2.
The same day, php.net announced 8.6.0 RC2 as the first RC, because RC1 had a packaging mistake. But this post is not another 8.6 feature tour. I already wrote that for PHP 8.6: What's Coming and What I'd Watch Before Upgrade Day. This is about the security batch and what it means for production.
Quick Answer
Land on 8.2.34 if you are on 8.2, 8.3.35 if you are on 8.3, 8.4.26 if you are on 8.4, or 8.5.11 if you are on 8.5. All four releases are security patches. No feature changes, no new APIs, just fixes.
CVE-2026-91766: The HTTP redirect credential leak
The lead CVE is CVE-2026-91766, tracked as GHSA-fpwc-w8rq-cr92. Before the fix, the HTTP stream wrapper in file_get_contents() and fopen() sent Authorization, Cookie, and Proxy-Authorization headers across cross-origin redirects. That includes redirects that changed the scheme (HTTPS to HTTP), the host, or the port.
If you called file_get_contents() with follow_location enabled (it is on by default) and passed an Authorization: Bearer header in the stream context, and the API answered with a 302 redirect to another host, your token went to that other host too.
curl fixed the same class of bug in January 2018 (CVE-2018-1000007). curl had to ship a second fix in April 2022 (CVE-2022-27776) because the first one only compared the host name, so a port or scheme change on the same host still leaked credentials. PHP had both bugs until this release.
The fix parses the new URL before freeing the old one, compares the scheme, host, and port (with default ports filled in), and strips authorization, cookie, and proxy-authorization from the header bag on cross-origin redirects. Once stripped, they stay gone for every later hop. A redirect that comes back to the original host does not get the token back either.
The write-up from Timothée Daubois (who did the fix with Jakub Zelenka) notes a CVSS 3.1 score of 5.9 and walks the history and the messy strip_header() details. Worth reading if you work on SDKs or HTTP clients.
One sharp edge. The fix strips three header names and no more. If your credentials travel in X-Api-Key or any other custom header, set follow_location to 0 and follow the redirect yourself after checking where it points, because the wrapper will not.
Other CVEs worth a Laravel/production mention
The other CVEs from the ChangeLog-8.php entries for 8.5.11 and 8.4.26:
CVE-2026-91768 (GHSA-62xp-839h-2637): FPM IPv6 ACL bypass in listen.allowed_clients. The check compared partial addresses, so a crafted IPv6 address could bypass the ACL. If you rely on listen.allowed_clients with IPv6, this matters.
CVE-2026-91769 and CVE-2026-91767: OpenSSL TLS hostname verification issues. 91769 is "TLS hostname verification falls back to CN after SAN mismatch." 91767 is "Heap buffer overflow in php_openssl_matches_wildcard_name() on crafted server certificate wildcard CN." Both are TLS client verification bugs. If you connect to HTTPS APIs or SMTP/IMAP over TLS from PHP, patch the runtime.
CVE-2026-93682: Out-of-bounds read in the HTTP stream wrapper when following a redirect with an empty Location header. Same wrapper, different edge case.
CVE-2026-92842: Out-of-bounds read in convert.* stream filters when line-break-chars contains NUL.
CVE-2026-91765 and CVE-2025-14181: SOAP issues. 91765 is "Unbounded recursion in server-side cleanup_xml_node()." 14181 is "Integer overflow to buffer overflow in SOAP HTTP parsing." If you run a SOAP server or parse untrusted WSDL, patch.
CVE-2025-1218: mysqlnd packet overreads (GHSA-r6x9-5r99-36j7). "Various packet overreads in mysqlnd wire protocol." If you use MySQL with mysqlnd (the default), patch.
CVE-2026-6103: Phar TAR entry injection. "Integer overflow in phar_tar_number() allowing TAR archive entry injection."
CVE-2026-17545: Windows reserved device names. "Reserved device names are not rejected before file and stream I/O." Windows only.
I am not inventing severity rankings here. The ChangeLog lists these CVEs. Daubois notes 5.9 for 91766. The rest do not have public scores in the sources I checked. Read the ChangeLog for the full list.
Laravel angle
Laravel's HTTP client usually uses Guzzle and cURL under the hood, not the PHP stream wrapper. But stream wrappers still appear in older helpers, file_get_contents() HTTP calls, some SDKs, and custom code. If you wrote file_get_contents() with an Authorization header and follow_location, you hit 91766.
The FPM ACL bug (91768) matters if you rely on listen.allowed_clients with IPv6. The OpenSSL TLS bugs (91769, 91767) matter if you connect to HTTPS APIs from PHP, which is most Laravel apps. The mysqlnd bug (1218) matters if you use MySQL, which is also most Laravel apps.
Patch the runtime regardless. These are not Laravel framework bugs. These are runtime bugs that affect any PHP code running on an unpatched version.
The 8.6 RC2 aside
Same day, php.net announced PHP 8.6.0 RC2 as the first RC. RC1 had a packaging mistake (API number bump, per the announcement and scherzer.dev), so RC2 is the one to test. The GA date is still aimed at 19 Nov 2026.
I already covered the 8.6 features and the beta3 smoke test in the earlier post. PFA, clamp(), SortDirection, secure session defaults, and the rest. I am not rehashing that here. If you want the feature story, read PHP 8.6: What's Coming and What I'd Watch Before Upgrade Day.
Test RC2 if you are planning to upgrade after GA. Do not skip RC1 smoke tests just because RC1 itself was skipped. RC2 is for smoke tests, not for production.
My take
Patch production first. The credential leak (91766) is real, the FPM ACL bypass (91768) is real, the OpenSSL bugs (91769, 91767) are real, the mysqlnd bug (1218) is real. Four security releases in one day is a batch worth landing.
RC2 is for smoke tests only. Do not put production on a release candidate. Do not skip the security patch because you are excited about clamp() and PFA. Patch to 8.2.34, 8.3.35, 8.4.26, or 8.5.11, then test RC2 on a throwaway binary.
If your deploy pipeline is automated and you pin minor versions, this should be a drop-in. If you pin exact versions, update the lock file. If you run Laravel on Forge or Herd, wait for the images to catch up before you expect the new runtime in the UI.
And if you wrote file_get_contents() with follow_location and an Authorization header in a stream context, audit those calls. Set follow_location to 0 and follow the redirect yourself if you use custom credential headers. The fix strips three header names. Custom headers are not on that list.
Sources
- PHP archive 2026 (24 Sep entries for 8.2.34, 8.3.35, 8.4.26, 8.5.11, and 8.6.0 RC2)
- PHP ChangeLog-8.php (sections for 8.5.11 and 8.4.26)
- GitHub Security Advisory GHSA-fpwc-w8rq-cr92
- Timothée Daubois: CVE-2026-91766: PHP had the redirect credential leak curl fixed in 2018
- Daniel Scherzer: No PHP 8.6 RC1
- PHP.Watch: PHP 8.6.0RC2
Comments
No comments yet
Loading comments...