Description
when php_stream_url_wrap_http_ex() attempts to generate an auth header, it will php_url_decode() both resource->user and resource->password (which decodes them in place) but it DOES NOT update the zend string length (e.g. ZSTR_LEN(...) = php_url_decode(...);) which will now be shorter if anything was decoded.
from https://github.com/php/php-src/blob/9898293af99611f1c77dea3cfa332500ca49931f/ext/standard/http_fopen_wrapper.c#L753-L780
/* auth header if it was specified */
if (((have_header & HTTP_HEADER_AUTH) == 0) && resource->user) {
smart_str scratch = {0};
/* decode the strings first */
php_url_decode(ZSTR_VAL(resource->user), ZSTR_LEN(resource->user));
smart_str_append(&scratch, resource->user);
smart_str_appendc(&scratch, ':');
/* Note: password is optional! */
if (resource->password) {
php_url_decode(ZSTR_VAL(resource->password), ZSTR_LEN(resource->password));
smart_str_append(&scratch, resource->password);
}
zend_string *scratch_str = smart_str_extract(&scratch);
zend_string *stmp = php_base64_encode((unsigned char*)ZSTR_VAL(scratch_str), ZSTR_LEN(scratch_str));
smart_str_appends(&req_buf, "Authorization: Basic ");
smart_str_append(&req_buf, stmp);
smart_str_appends(&req_buf, "\r\n");
php_stream_notify_info(context, PHP_STREAM_NOTIFY_AUTH_REQUIRED, NULL, 0);
zend_string_efree(scratch_str);
zend_string_free(stmp);
}
If either auth component contains url encoded characters, the value used to generate the auth header will be [decoded value][null][remaining non-decoded buffer] instead of just the decoded value. e.g.
// will send:
// Authorization: Basic dm9ydGZ1ADcyJTc0JTY2JTc1OnBhc3N3b3JkACU3MyU3NyU2ZiU3MiU2NA==
// (vortfu[NULL]72%74%66%75:password[NULL]%73%77%6f%72%64)
//
// instead of:
// Authorization: Basic dm9ydGZ1OnBhc3N3b3Jk
// (vortfu:password)
file_get_contents( 'http://%76%6f%72%74%66%75:%70%61%73%73%77%6f%72%64@127.0.0.1/auth' );
PHP Version
PHP 8.6.0-dev (cli) (built: May 27 2026 08:59:55) (NTS DEBUG)
Copyright (c) The PHP Group
Zend Engine v4.6.0-dev, Copyright (c) Zend Technologies
with Zend OPcache v8.6.0-dev, Copyright (c), by Zend Technologies
Operating System
No response
Description
when
php_stream_url_wrap_http_ex()attempts to generate an auth header, it willphp_url_decode()bothresource->userandresource->password(which decodes them in place) but it DOES NOT update the zend string length (e.g.ZSTR_LEN(...) = php_url_decode(...);) which will now be shorter if anything was decoded.from
https://github.com/php/php-src/blob/9898293af99611f1c77dea3cfa332500ca49931f/ext/standard/http_fopen_wrapper.c#L753-L780If either auth component contains url encoded characters, the value used to generate the auth header will be
[decoded value][null][remaining non-decoded buffer]instead of just the decoded value. e.g.PHP Version
Operating System
No response