CVE-2025-1220
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 fsockopen() and stream_socket_client() functions open network connections to a host name and port given by the script.
A Server-Side Request Forgery (SSRF) vulnerability (CVE-2025-1220) has been identified in the socket transports of PHP's streams layer, which allows an attacker who supplies a host name containing a NUL byte to an application that checks the name and then connects to it to make PHP connect to a different host than the one the application checked. PHP tracks this issue as GHSA-3cr5-j632-f35r.
Per MITRE CWE-918: The web server receives a URL or similar request from an upstream component and retrieves the contents of this URL, but it does not sufficiently ensure that the request is being sent to the expected destination.
This issue affects all versions of PHP before 8.1.33, PHP 8.2 before 8.2.29, PHP 8.3 before 8.3.23 and PHP 8.4 before 8.4.10, including 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
- Product: PHP
- Affected packages:
php-src(ext/standard,main/streams) - Affected versions: <8.1.33, >=8.2.0 <8.2.29, >=8.3.0 <8.3.23, >=8.4.0 <8.4.10
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 8.1.33, 8.2.29, 8.3.23, 8.4.10
- NES for PHP 5.6.1 (based on PHP 5.6.40)
- NES for PHP 7.2.1 (based on PHP 7.2.34)
- NES for PHP 7.4.1 (based on PHP 7.4.33)
Vulnerability Info
This Low-severity vulnerability is found in PHP before 8.1.33, 8.2 before 8.2.29, 8.3 before 8.3.23 and 8.4 before 8.4.10. The CVE record does not list the End-of-Life PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4 and 8.0 release lines, but they carry the same code and never received the upstream fix. The PHP project scores it 3.7 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N).
PHP strings can contain NUL bytes, but the socket transports behind fsockopen() and stream_socket_client() did not check the host name for them and used it as a C string, which ends at the first NUL byte. A host name such as localhost\0.example.com therefore connects to localhost. Functions such as parse_url(), which an application may use to check the host name before connecting, see the whole string.
An application that only allows connections to hosts under a certain domain, or that otherwise validates an attacker-supplied host name with string functions, can be made to connect to a different host, such as a service on the local machine or the internal network. The CVE record notes that this opens the way to security problems when user code implements access checks before connecting.
Exploitation needs an application that connects with fsockopen(), pfsockopen() or a socket stream to a host name an attacker influences, after checking that name with string functions. This applies to any SAPI. Applications that never connect to user-supplied host names are not exposed.
The fix refuses a host name that contains a NUL byte, and makes fsockopen() keep the full host name when it adds the port. In the upstream code the check in the socket transport reads:
if (memchr(str, '\0', str_len)) {
*err = ZSTR_INIT_LITERAL("The hostname must not contain null bytes", 0);
return NULL;
}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.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 8.1.33, 8.2.29, 8.3.23, 8.4.10, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- Jihwan Kim (finder)
- Jakub Zelenka (remediation)