Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-85c2-q967-79q5

Опубликовано: 07 мая 2026
Источник: github
Github: Не прошло ревью
CVSS4: 9.4

Описание

Use-After-Free in SOAP using Apache map with Remote Code Execution

ext-soap supports deduplicating objects in the XML graph through id and href. When traversing the XML graph, ext-soap will remember all plain PHP objects using the hash map SOAP_GLOBAL(ref_map), where the pointer to the libxml2 node acts as a key, and the PHP object as a value. This happens in soap_add_xml_ref().

https://github.com/php/php-src/blob/dcf653339c245e25ea319248d0fc071a9405d688/ext/soap/php_encoding.c#L349-L354

Crucially, the reference count of the PHP object is not increased. Normally this is not a problem, as all objects in the XML graph are stored in the resulting object graph and cannot be freed.

soap_check_xml_ref() does the opposite of soap_add_xml_ref(); it will check whether some libxml2 node as already been evaluated and stored in SOAP_GLOBAL(ref_map).

https://github.com/php/php-src/blob/dcf653339c245e25ea319248d0fc071a9405d688/ext/soap/php_encoding.c#L331-L347

The Apache map offers a mechanism to free objects between these two points by overwriting existing map entries.

class Handler { public function test($map, $stale) { global $result; $result = $stale; } } $envelope = <<<'XML' <?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soapenv:Body> <test> <map xsi:type="apache:Map" xmlns:apache="http://xml.apache.org/xml-soap"> <item> <key>somekey</key> <value id="stale"><object>Stale</object></value> </item> <item> <key>somekey</key> <value></value> </item> </map> <stale href="#stale"/> </test> </soapenv:Body> </soapenv:Envelope> XML; $s = new SoapServer(null, ['uri' => 'urn:a']); $s->setClass(Handler::class); $s->handle($envelope); var_dump($result);

This example will:

  • evaluate the map node
  • evaluate the Stale object, which includes calling calling soap_add_xml_ref() to remember it in SOAP_GLOBAL(ref_map)
  • add the resulting object to a temporary map, which will be the result of the Apache map node
  • overwrite the object immediately with NULL for the <item> with an empty <value>, releasing the Stale object only strongly referenced by the temporary map, with the reference in SOAP_GLOBAL(ref_map) becoming stale
  • have <stale href="#stale"/> refer to this stale pointer within SOAP_GLOBAL(ref_map), reusing the freed memory

After this code, $result will refer to the stale memory where Stale was previously allocated. The attacker has high control over this memory segment by subsequently allocating plain strings, leading to Remote Code Execution.

The solution is straight forward, namely increase the reference count before adding objects to SOAP_GLOBAL(ref_map), and configure a ZVAL_PTR_DTOR deallocator to release the objects when the procedure is done.

Пакеты

Наименование

ext-soap

php
Затронутые версииВерсия исправления

< 8.2.31

8.2.31

Наименование

ext-soap

php
Затронутые версииВерсия исправления

< 8.3.31

8.3.31

Наименование

ext-soap

php
Затронутые версииВерсия исправления

< 8.4.21

8.4.21

Наименование

ext-soap

php
Затронутые версииВерсия исправления

< 8.5.6

8.5.6

EPSS

Процентиль: 39%
0.00505
Низкий

9.4 Critical

CVSS4

Дефекты

CWE-416

Связанные уязвимости

CVSS3: 9.8
ubuntu
около 1 месяца назад

In PHP versions 8.2.* before 8.2.31, 8.3.* before 8.3.31, 8.4.* before 8.4.21, and 8.5.* before 8.5.6, the SOAP extension's object deduplication mechanism stores pointers to PHP objects in a global map without incrementing their reference counts. When an apache:Map node contains duplicate keys, processing the second entry overwrites the first in the temporary result map, freeing the original PHP object while its stale pointer remains in the map. A subsequent href reference to the freed node can copy the dangling pointer into the result. As PHP string allocations can reclaim the freed memory region, an attacker with control over the SOAP request body can exploit this use-after-free to achieve remote code execution.

CVSS3: 7.7
redhat
около 1 месяца назад

In PHP versions 8.2.* before 8.2.31, 8.3.* before 8.3.31, 8.4.* before 8.4.21, and 8.5.* before 8.5.6, the SOAP extension's object deduplication mechanism stores pointers to PHP objects in a global map without incrementing their reference counts. When an apache:Map node contains duplicate keys, processing the second entry overwrites the first in the temporary result map, freeing the original PHP object while its stale pointer remains in the map. A subsequent href reference to the freed node can copy the dangling pointer into the result. As PHP string allocations can reclaim the freed memory region, an attacker with control over the SOAP request body can exploit this use-after-free to achieve remote code execution.

CVSS3: 9.8
nvd
около 1 месяца назад

In PHP versions 8.2.* before 8.2.31, 8.3.* before 8.3.31, 8.4.* before 8.4.21, and 8.5.* before 8.5.6, the SOAP extension's object deduplication mechanism stores pointers to PHP objects in a global map without incrementing their reference counts. When an apache:Map node contains duplicate keys, processing the second entry overwrites the first in the temporary result map, freeing the original PHP object while its stale pointer remains in the map. A subsequent href reference to the freed node can copy the dangling pointer into the result. As PHP string allocations can reclaim the freed memory region, an attacker with control over the SOAP request body can exploit this use-after-free to achieve remote code execution.

msrc
19 дней назад

Use-After-Free in SOAP using Apache map

CVSS3: 9.8
debian
около 1 месяца назад

In PHP versions 8.2.* before 8.2.31, 8.3.* before 8.3.31, 8.4.* before ...

EPSS

Процентиль: 39%
0.00505
Низкий

9.4 Critical

CVSS4

Дефекты

CWE-416