Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

External entities not working in simplexml

Tags:

php

xml

I am parsing XML using SimpleXML in PHP 5 and external entities are not working. The XML parses, but the entities just are blank. The underlying library is libxml2.

This is the code:

libxml_disable_entity_loader(false);
simplexml_load_file($target_file);

It parses the XML as expected, but doesn't resolve the external entities and seems to ignore them.

like image 562
chs Avatar asked Sep 29 '22 04:09

chs


1 Answers

This is the expected behavior, because you need to tell when loading the document to expand (and therefore remove) these entities:

libxml_disable_entity_loader(false);
simplexml_load_file($target_file, 'SimpleXMLElement', LIBXML_NOENT);
                                                      ############

This constant is also cross-linked on the manual page of libxml_disable_entity_loader.

The function itself only enables or disables the default entity loader. Additionally the parser needs to be told via the libxml2 based option flag, that those entities should be substituted. Only then the default loader (or if you have set it to a different one) would kick in.

Online Demo:

<?php
/**
 * @link https://stackoverflow.com/a/29864193/367456
 */

$buffer = <<<XML
<?xml version="1.0"?>
 <!DOCTYPE foo [  
  <!ELEMENT foo ANY >
  <!ENTITY xxe SYSTEM "data://text/plain,test" >]><foo>&xxe;</foo>
XML;

libxml_disable_entity_loader(false);

$xml = simplexml_load_string($buffer);
$xml->asXML('php://output');

$xml = simplexml_load_string($buffer, 'SimpleXMLElement', LIBXML_NOENT);
$xml->asXML('php://output');

Output for 5.2.11 - 5.6.8, php7@20140507 - 20150401, hhvm-3.5.0 - 3.6.1

<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "data://text/plain,test">
]>
<foo>&xxe;</foo>
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo ANY>
<!ENTITY xxe SYSTEM "data://text/plain,test">
]>
<foo>test</foo>

The XML is based on the exploit examples outlined on XML External Entity (XXE) Processing (OWASP Wiki) and modified for the PHP demonstration regarding your question.

And more important than PHP versions is the version of libxml both on system and the binding in PHP. Just saying in case the 3v4l.org demo code creates the impression that it always behaved the same in all PHP versions - this just must not be the case.

Related Q&A

  • Clarifications on XXE vulnerabilities throughout PHP versions (Jun 2014)
  • Check for malicious XML before allowing DTD loading? (Jul 2014)
like image 50
hakre Avatar answered Oct 13 '22 01:10

hakre