SoapClient followed any Location header, so a redirect to another host,
port, or scheme resent the HTTP authentication credentials, the stream
context headers, and the SOAP envelope to that origin. Such redirects now
fail with a SoapFault. A same-host upgrade from http to https on port 443
is still followed. The new follow_cross_origin_redirects option restores
the previous behavior. Cookies were already scoped by domain and
Proxy-Authorization only reaches the proxy, so neither changes.
Fixes GH-24315
- Replace bailout on OOM with UnwindExit
- Properly reset various globals that may be accessed during startup
Fix GHSA-w8hw-w9fx-j79w (CVE-2026-109618)
Fix GHSA-6wmf-4rv5-p3rp (CVE-2026-109619)
Co-authored-by: Ilija Tovilo <ilija.tovilo@me.com>
Co-authored-by: Jakub Zelenka <bukka@php.net>
Co-authored-by: Nora Dossche <7771979+ndossche@users.noreply.github.com>
Co-authored-by: Nicolas Grekas <nicolas.grekas@gmail.com>
A short read of a Content-Length body returned the bytes received and left
the keep-alive socket cached. Return failure instead, which closes that
socket and raises the existing HTTP fault.
* PHP-8.5:
Skip bz2 GH-20807 test when less than 13 GiB of memory is available
ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable
Add NEWS entries
ext/standard: Fix 1-char relative Location redirects after GH-23467
[http] Fix out-of-bounds read on empty Location header
Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED
Fix GHSA-9f67-6fw4-hpfp
Fix GHSA-j3wh-g957-2m85: phar tar entry injection
Fix GHSA-cj93-vc83-wgqv
Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding
Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects
Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol
Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name()
Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID
Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses
Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars
# Conflicts:
# NEWS
# ext/openssl/xp_ssl.c
# ext/phar/tar.c
# ext/soap/php_http.c
# ext/standard/http_fopen_wrapper.c
* PHP-8.4:
Skip bz2 GH-20807 test when less than 13 GiB of memory is available
ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable
Add NEWS entries
ext/standard: Fix 1-char relative Location redirects after GH-23467
[http] Fix out-of-bounds read on empty Location header
Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED
Fix GHSA-9f67-6fw4-hpfp
Fix GHSA-j3wh-g957-2m85: phar tar entry injection
Fix GHSA-cj93-vc83-wgqv
Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding
Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects
Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol
Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name()
Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID
Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses
Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars
# Conflicts:
# NEWS
# ext/phar/tar.c
# ext/soap/php_http.c
# ext/soap/php_xml.c
# ext/standard/http_fopen_wrapper.c
# win32/ioutil.c
* PHP-8.3:
ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable
Add NEWS entries
ext/standard: Fix 1-char relative Location redirects after GH-23467
[http] Fix out-of-bounds read on empty Location header
Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED
Fix GHSA-9f67-6fw4-hpfp
Fix GHSA-j3wh-g957-2m85: phar tar entry injection
Fix GHSA-cj93-vc83-wgqv
Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding
Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects
Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol
Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name()
Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID
Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses
Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars
# Conflicts:
# ext/openssl/xp_ssl.c
* PHP-8.2:
ext/soap: make GHSA-cj93-vc83-wgqv test lean and reliable
Add NEWS entries
ext/standard: Fix 1-char relative Location redirects after GH-23467
[http] Fix out-of-bounds read on empty Location header
Fix GHSA-ch8v-r6jh-4vvr: encode 0xFF in FILTER_SANITIZE_ENCODED
Fix GHSA-9f67-6fw4-hpfp
Fix GHSA-j3wh-g957-2m85: phar tar entry injection
Fix GHSA-cj93-vc83-wgqv
Fix GHSA-rgrp-mwpx-f6rm: unbounded recursion in ext/soap XML parsing and decoding
Fix GHSA-fpwc-w8rq-cr92: strip credentials from user headers on cross-origin redirects
Fix GHSA-r6x9-5r99-36j7: Various packet overreads in mysqlnd wireprotocol
Fix GHSA-xr7j-rvgx-xq5p: OOB read in php_openssl_matches_wildcard_name()
Fix GHSA-vvx9-73fr-5jjx: do not fall back to CN if the cert has a service ID
Fix GHSA-62xp-839h-2637: FastCGI allowed_clients compared only 96 bits of IPv6 addresses
Fix heap-buffer-overflow in convert stream filters with NUL in line-break-chars
Commit 3dcdb9826b routed the user_agent option through a truncate-and-warn
check, but the Content-Type context option, the soapaction and the cookie
names and values reach the same request buffer unchecked, so a CR/LF in any
of them still injects arbitrary request headers.
Emit all of them through that same check. The helper now takes an explicit
length so the char* soapaction can share it.
Close GH-22781
GH-17976 sanitized user_agent where the HTTP wrapper emits headers and left
the SOAP client alone, so a value carrying CRLF still injects request headers
through all three of its sources: the SoapClient user_agent option, the
http.user_agent stream context option, and the ini setting. Resolve the three
to one zend_string and emit it through the same truncate-and-warn check the
HTTP wrapper applies.
Closes GH-22771
make_http_soap_request() looked for the reason phrase with strstr(tmp, " ")
even when the first strstr() found no space, which happens for a status line
carrying a version but no status code, such as "HTTP/1.1". tmp is NULL there,
so strstr() dereferenced it and the client crashed.
Only parse the reason phrase when a status code field was present.
Closes GH-22761
Followup-PR for #21724. Using the new API in #21724 to replace dependencies
on /ext/hash in
- ext/opcache/ZendAccelerator/
- ext/soap/php_http.c
- Zend/zend_system_id.c
In the following ext, there are independent implementation of bin2hex. This PR
also change them to directly using the new Zend API.
- ext/standard/string.c
- ext/hash/php_hash.h
When a redirect Location is a protocol-relative reference (//host/path),
the URI parser already fills new_uri->host, but the scheme-less redirect
handling overwrote it with a copy of the request host without releasing
the parsed one. That leaks a zend_string per such redirect and pins the
redirect back to the original host instead of the one the server named.
Inherit host and port from the request URI only when new_uri->host is
NULL, mirroring the scheme guard directly above.
When a redirect Location is a protocol-relative reference (//host/path),
php_url_parse() already fills new_url->host, but the scheme-less redirect
handling overwrote it with a copy of the request host without releasing
the parsed one. That leaks a zend_string per such redirect and pins the
redirect back to the original host instead of the one the server named.
Inherit host and port from the request URL only when new_url->host is
NULL, mirroring the scheme guard directly above.
Closes GH-22434
The from and user_agent INI settings and the user_agent stream context
option were written into HTTP request headers without stripping CR/LF
characters, allowing header injection.
Truncate at the first \r or \n and emit E_WARNING. The from and
user_agent globals are stored as zend_string so the check scans the
full length and a NUL byte no longer pre-truncates the value before the
CR/LF scan.
Fixes GH-17976
The HTTP redirect handler inherited scheme, host and port from the newly
parsed Location URI itself instead of the previous request URI, so a
scheme-less (relative or absolute-path) Location left the host NULL and
the retry aborted with "Unable to parse URL". Read the inherited
components and the path base from the request URI, restoring the
behaviour the URI-parser refactor changed.
Closes GH-22341
The cookie option parser uses a wrong offset to start scanning
attributes, causing cookie values containing substrings like
"path=" or "domain=" to be falsely matched as attributes.
close GH-21400
* uri: Rename `uri_recomposition_mode_t` to `php_uri_recomposition_mode`
* uri: Align the names of the `php_uri_recomposition_mode` values
* uri: Rename `uri_component_read_mode_t` to `php_uri_component_read_mode`
* uri: Align the names of the `php_uri_component_read_mode` values
* uri: Rename `uri_property_name_t` to `php_uri_property_name`
* uri: Align the names of the `php_uri_property_name` values
* uri: Rename `uri_property_handler_t` to `php_uri_property_handler`
* uri: Rename `uri_(read|write)_t` to `php_uri_property_handler_(read|write)`
* uri: Rename `php_uri_property_handler`’s `(read|write)_func` to `read|write`
The `_func` is implied by the data type and the name of the struct.
* uri: Rename `uri_parser_t` to `php_uri_parser`
* uri: Shorten the names of `php_uri_parser` fields
The `_uri` suffix is implied, because this is an URI parser.
By using the `zend_hash_*()` functions directly, we can benefit from the
precalculated hash value in the given `zend_string *uri_parser_name`. We need
to deconstify the parameter, since the function might calculate the hash, thus
modifying the `zend_string*`.