CVE-2025-1861

Improper Input Validation (4.16)
Affects
PHP
in
PHP
No items found.
Versions
<8.1.32, >=8.2.0 <8.2.28, >=8.3.0 <8.3.19, >=8.4.0 <8.4.5

Patch Available.

Exclamation circle icon
Patch Available

This Vulnerability has been fixed in the Never-Ending Support (NES) version offered by HeroDevs.

Overview

PHP is a general-purpose scripting language used mostly for web development. It runs behind web servers through server APIs such as Apache mod_php and PHP-FPM, and powers content management systems and frameworks such as WordPress, Drupal, Moodle and Laravel. Its HTTP stream wrapper lets functions such as file_get_contents() and fopen(), and the extensions that load URLs through PHP streams, fetch http:// and https:// URLs, and it follows redirects by default.

An Improper Input Validation vulnerability (CVE-2025-1861) has been identified in PHP's HTTP stream wrapper, which allows a server that answers a request with a redirect, or an attacker who can answer for it, to send a Location longer than 1024 bytes that PHP silently truncates, so that the client follows a different URL than the one the server sent. PHP tracks this issue as GHSA-52jp-hrpf-2jff.

Per MITRE CWE-131: The product does not correctly calculate the size to be used when allocating a buffer, which could lead to a buffer overflow.

This issue affects PHP before 8.1.32, PHP 8.2 before 8.2.28, PHP 8.3 before 8.3.19 and PHP 8.4 before 8.4.5, which includes the End-of-Life release lines PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 through their final releases.

Details

Module Info

Vulnerability Info

This Medium-severity vulnerability is found in the HTTP stream wrapper of PHP before 8.1.32, 8.2 before 8.2.28, 8.3 before 8.3.19 and 8.4 before 8.4.5, including the End-of-Life PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 release lines, which never received the upstream fix. The PHP project scores it 6.3 under CVSS 4.0 (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N) and classifies it as CWE-131, Incorrect Calculation of Buffer Size.

When an HTTP response carries a Location header, php_stream_url_wrap_http_ex() stores its value and, if the redirect is to be followed, builds the next URL from it and opens that instead. The value was kept in a stack buffer of HTTP_HEADER_BLOCK_SIZE (1024) bytes, and the URL built from a relative location in buffers of the same size. In PHP 7.4.33, the header is copied like this:

if (!strncasecmp(http_header_line, "Location:", sizeof("Location:")-1)) {
    if (context && (tmpzval = php_stream_context_get_option(context, "http", "follow_location")) != NULL) {
        follow_location = zval_is_true(tmpzval);
    } else if (!((response_code >= 300 && response_code < 304)
            || 307 == response_code || 308 == response_code)) {
        /* we shouldn't redirect automatically
        if follow_location isn't set and response_code not in (300, 301, 302, 303 and 307)
        see http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.1
        RFC 7238 defines 308: http://tools.ietf.org/html/rfc7238 */
        follow_location = 0;
    }
    strlcpy(location, http_header_value, sizeof(location));

strlcpy() stops at the size of the buffer, so a longer Location is cut without any error, and PHP requests the truncated URL. RFC 9110 recommends that clients support at least 8000 bytes, and the CVE record notes that the limit may lead to incorrect URL truncation and redirecting to a wrong location. The request may then reach a different path, query string or resource than the redirecting server intended, and the response is returned to the application as if it were the right one.

Exploitation needs an application that fetches a URL with the HTTP stream wrapper, with allow_url_fopen enabled and redirects followed (the default), from a server an attacker controls or can impersonate, for example over plain HTTP. HeroDevs' analysis confirms the same behavior on PHP 5.6, 7.2 and 7.4 from any server API. Applications that do not fetch remote URLs through PHP streams, or that disable follow_location, are not exposed.

The fix keeps the Location value on the heap with its full length, builds the redirect target with spprintf(), and makes the request fail if the Location exceeds a new limit of a little over 8 KB, in line with the RFC 9110 recommendation.

Mitigation

The PHP project publishes security fixes only for its supported release lines. PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 are End-of-Life and will not receive any public updates to address this issue.

Until an upgrade is possible, set the follow_location stream context option to 0 and handle redirects in application code, or use an HTTP client that does not limit the Location header length.

Users of the affected components should apply one of the following mitigations:

  • Upgrade to PHP 8.1.32, 8.2.28, 8.3.19, 8.4.5, or later.
  • Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.

Credits

Vulnerability Details
Severity
Level
CVSS Assessment
Low
>=0 <4
Medium
>=4 <6
High
>=6 <8
Critical
>=8 <10
Medium
ID
CVE-2025-1861
PROJECT Affected
PHP
Versions Affected
<8.1.32, >=8.2.0 <8.2.28, >=8.3.0 <8.3.19, >=8.4.0 <8.4.5
NES Versions Affected
Published date
March 30, 2025
≈ Fix date
February 27, 2025
Fixed in
Category
Improper Input Validation (4.16)
Vex Document
Download VEXHow do I use it?
Sign up for the latest vulnerability alerts fixed in
PHP
Rss feed icon
Subscribe via RSS
or

By submitting the form I acknowledge receipt of our Privacy Policy.

Thanks for signing up for our Newsletter! We look forward to connecting with you.
Oops! Something went wrong while submitting the form.