Описание
Integer overflow to buffer overflow in soap HTTP parsing
Summary
The SOAP HTTP client guards its response buffer growth with a check that relies on signed integer overflow, which is undefined behaviour and is not guaranteed to trigger. When the check is optimised away, a malicious SOAP server can make the client allocate a buffer far smaller than the data it then writes into it, producing a heap buffer overflow.
Details
get_http_body() in ext/soap/php_http.c accumulates chunked response data and checks for overflow like this:
https://github.com/php/php-src/blob/php-8.5.10/ext/soap/php_http.c#L1494-L1499
http_buf_size and buf_size are both int, so http_buf_size + buf_size + 1 < 0 can only become true through signed integer overflow. That is undefined behaviour, and a compiler is free to assume it never happens and remove the branch. This was tested with Clang 20.1.7 and GCC 15.1.1, where the check did not trigger; other compilers and versions may behave differently, so the check cannot be relied upon.
Once the check is gone, zend_string_realloc() is reached with a length such as 18446744073709551614. Adding the zend_string header overflows again, far too few bytes are allocated, and the following read loop writes past the end of the allocation.
The fix switches the accumulated size to size_t, bounds each growth step against ZSTR_MAX_LEN before allocating, and uses zend_string_safe_realloc() so the multiplication and addition are checked.
PoC
A SOAP server that responds with Transfer-Encoding: chunked and declares a chunk size of 0x7fffffff, followed by a second chunk header of the same size, drives the buffer size past INT_MAX on the reallocation for the second chunk. The regression test ext/soap/tests/bugs/GHSA-cj93-vc83-wgqv.phpt reproduces this against a local server. It needs several gigabytes of free memory, since the overflow is only reached after a genuinely large buffer has been built.
Impact
A malicious SOAP server, or a man-in-the-middle on a plaintext SOAP connection, can overflow a heap buffer in a SoapClient that talks to it. The consequences depend on the heap layout and the compiler used to build PHP, ranging from a crash to memory corruption.
The bug only manifests on builds where the compiler discards the undefined signed-overflow check, and it requires the client to accept a multi-gigabyte response. Setting a low memory_limit causes an out-of-memory error before the overflow is reached and serves as a workaround.
Пакеты
php
>=8.2.0, <8.2.34
8.2.34
php
>=8.3.0, <8.3.35
8.3.35
php
>=8.4.0, <8.4.26
8.4.26
php
>=8.5.0, <8.5.11
8.5.11
Связанные уязвимости
The SOAP HTTP client guards its response buffer growth with a check that relies on signed integer overflow, which is undefined behaviour and is not guaranteed to trigger. When the check is optimised away, a malicious SOAP server can make the client allocate a buffer far smaller than the data it then writes into it, producing a heap buffer overflow.
The SOAP HTTP client guards its response buffer growth with a check that relies on signed integer overflow, which is undefined behaviour and is not guaranteed to trigger. When the check is optimised away, a malicious SOAP server can make the client allocate a buffer far smaller than the data it then writes into it, producing a heap buffer overflow.
The SOAP HTTP client guards its response buffer growth with a check that relies on signed integer overflow, which is undefined behaviour and is not guaranteed to trigger. When the check is optimised away, a malicious SOAP server can make the client allocate a buffer far smaller than the data it then writes into it, producing a heap buffer overflow.
The SOAP HTTP client guards its response buffer growth with a check th ...