Skip to content

Fix out-of-bounds read on empty Location header in HTTP wrapper - #23467

Open
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/http-empty-location-84
Open

Fix out-of-bounds read on empty Location header in HTTP wrapper#23467
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/http-empty-location-84

Conversation

@iliaal

@iliaal iliaal commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

When a server sends a redirect with an empty Location header, the wrapper allocates a single byte for it and the relative-redirect branch then reads location[1], one byte past the allocation, so a hostile server can make the over-read pick up heap garbage and turn the redirect target into the current path plus junk instead of the host root. The second-byte dereference is now guarded by header_info.location_len; an empty Location deterministically redirects to the host root. Sibling audit found no other unguarded indexing of header_info.location.

Comment thread ext/standard/http_fopen_wrapper.c Outdated
char *loc_path = NULL;
if (*header_info.location != '/') {
if (*(header_info.location+1) != '\0' && resource->path) {
if (header_info.location_len > 0 && *(header_info.location+1) != '\0' && resource->path) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, this might not be related to your PR, but since it already have location_len, why it still call strlen(location) above?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to location_len.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you still need *(header_info.location+1) != '\0' tough ?

@iliaal iliaal Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. Empty Location is length 0. A 1-char relative path is valid, so location_len > 0 is enough.

iliaal added a commit to iliaal/php-src that referenced this pull request Aug 26, 2026
An empty Location header allocates a single byte for the NUL
terminator, so reading location[1] in the relative-redirect branch
over-reads heap memory and could append a garbage-derived path to the
redirect target instead of the correct host root. Guard the read with
location_len before dereferencing the second byte, and use that length
instead of strlen for the absolute-URL check.

Closes phpGH-23467
@iliaal
iliaal force-pushed the fix/http-empty-location-84 branch from 5e412a6 to 330bb1e Compare August 26, 2026 12:22
iliaal added a commit to iliaal/php-src that referenced this pull request Aug 26, 2026
An empty Location header allocates a single byte for the NUL
terminator, so reading location[1] in the relative-redirect branch
over-reads heap memory and could append a garbage-derived path to the
redirect target instead of the correct host root. Use location_len
instead of strlen, and require location_len > 1 before treating the
value as a relative path, so the second byte is never read.

Closes phpGH-23467
@iliaal
iliaal force-pushed the fix/http-empty-location-84 branch 2 times, most recently from 330bb1e to 8a54f0a Compare August 26, 2026 20:43
An empty Location header allocates a single byte for the NUL
terminator, so reading location[1] in the relative-redirect branch
over-reads heap memory and could append a garbage-derived path to the
redirect target instead of the correct host root. Use location_len
instead of strlen, and skip the relative join when location_len is 0,
so the second byte is never read.

Closes phpGH-23467
@iliaal
iliaal force-pushed the fix/http-empty-location-84 branch from 8a54f0a to 231f29f Compare August 26, 2026 20:53
@iliaal
iliaal requested review from devnexen and laruence August 26, 2026 20:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants