<?php
$str = <<<XML
<?xml version="1.0"?>
<!DOCTYPE doc [
<!ENTITY e SYSTEM "/tmp/exp">
]>
<tag>&e;</tag>
XML;
$xml = new SimpleXMLElement($str);
echo $xml;
?>
This should print out the contents of /tmp/exp
but does not and I don't understand why, even when I run the script with sudo
or change the /tmp/exp
file permissions to 777
.
CodePudding user response:
Loading of external entities is disabled by default, because it can lead to various security vulnerabilities.
To safely enable it, you need to register a custom entity loader, which can check for expected entity paths and decide whether to load them. For instance, you might allow any file in a particular directory, but not elsewhere on disk - you probably don't need to allow a reference to system files like /etc/passwd
. Or, you might map the path provided to a completely different location on your system.
You then also need to provide the LIBXML_NOENT
option to tell the parser to expand the entities via your handler.
For instance:
libxml_set_external_entity_loader(function($public, $system, $context) {
if ($system === '/tmp/exp') {
return fopen('/tmp/exp', 'r');
}
else {
return null;
}
});
$xml = new SimpleXMLElement($str, LIBXML_NOENT);