CVE-2025-14181
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 soap extension provides SoapClient, which sends SOAP requests to web services over HTTP and reads their responses.
An Integer Overflow vulnerability (CVE-2025-14181) has been identified in the HTTP response reader of PHP's SoapClient, which allows a malicious SOAP server, or an attacker who can answer in its place, to send a chunked response that makes the client allocate a buffer far smaller than the data it then writes into it, producing a heap buffer overflow. PHP tracks this issue as GHSA-cj93-vc83-wgqv.
Per MITRE CWE-190: The product performs a calculation that can produce an integer overflow or wraparound when the logic assumes that the resulting value will always be larger than the original value. This occurs when an integer value is incremented to a value that is too large to store in the associated representation. When this occurs, the value may become a very small or negative number.
This issue affects all versions of PHP before 8.2.34, PHP 8.3 before 8.3.35, PHP 8.4 before 8.4.26 and PHP 8.5 before 8.5.11.
Details
Module Info
- Product: PHP
- Affected packages:
php-src(ext/soap) - Affected versions: <8.2.34, >=8.3.0 <8.3.35, >=8.4.0 <8.4.26, >=8.5.0 <8.5.11
- GitHub repository: https://github.com/php/php-src
- Published packages: https://www.php.net/downloads
- Package manager: N/A
- Fixed in:
- OSS PHP 8.2.34, 8.3.35, 8.4.26, 8.5.11
- 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 Medium-severity vulnerability is found in the soap extension of all PHP versions before 8.2.34, PHP 8.3 before 8.3.35, 8.4 before 8.4.26 and 8.5 before 8.5.11, including the End-of-Life PHP 5.6, 7.0, 7.1, 7.2, 7.3, 7.4, 8.0 and 8.1 release lines, which never received the upstream fix. The PHP project scores it 6.5 under CVSS 3.1 (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:L/A:H).
When a SOAP server answers with Transfer-Encoding: chunked, get_http_body() reads each chunk's size from the response, grows its buffer by that amount and reads the chunk into it. The running body size and each chunk size were kept in signed int variables, and the only guard against overflow was a check that the sum is not negative. In PHP 7.4.33 the code reads:
if (sscanf(headerbuf, "%x", &buf_size) > 0 ) {
if (buf_size > 0) {
size_t len_size = 0;
if (http_buf_size + buf_size + 1 < 0) {
if (http_buf) {
zend_string_release_ex(http_buf, 0);
}
return NULL;
}
if (http_buf) {
http_buf = zend_string_realloc(http_buf, http_buf_size + buf_size, 0);
Signed integer overflow is undefined behavior in C, so the compiler may assume it never happens and remove the check. A server that sends chunk sizes whose sum wraps around can then make the client reallocate a buffer much smaller than the next chunk, and the read loop writes the chunk past the end of that buffer. HeroDevs' analysis found that on PHP 5.6 builds the wrapped size leads at least to a huge allocation that ends the request.
Exploitation needs an application that uses SoapClient to call a SOAP service (or load a WSDL) that an attacker controls or can impersonate, for example over plain HTTP or over HTTPS without certificate verification. It works in any SAPI with the soap extension loaded. Applications that only act as SOAP servers, or that do not use the extension, are not affected.
The fix keeps the sizes in unsigned types, checks each chunk against the largest possible string size before any arithmetic, and grows the buffer with an overflow-safe reallocation. Reading a body until the connection closes is bounded the same way. In PHP 8.2.34 the check reads:
if (buf_size >= ZSTR_MAX_LEN - http_buf_size) {
if (http_buf) {
zend_string_release_ex(http_buf, 0);
}
return NULL;
}
if (http_buf) {
http_buf = zend_string_safe_realloc(http_buf, 1, http_buf_size, buf_size, false);
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, 8.0 and 8.1 are End-of-Life and will not receive any public updates to address this issue.
Until an upgrade is possible, call SOAP services only over HTTPS with certificate verification enabled, so that an attacker on the network cannot answer in place of the service.
Users of the affected components should apply one of the following mitigations:
- Upgrade to PHP 8.2.34, 8.3.35, 8.4.26, 8.5.11, or later.
- Leverage a commercial support partner like HeroDevs (NES for PHP) for post-EOL security support.
Credits
- Nora Dossche (finder, remediation)