XML <!ENTITY e SYSTEM "/path/to/file"> 不适用于 PHP SimpleXMLElement
XML <!ENTITY e SYSTEM "/path/to/file"> does not work with PHP SimpleXMLElement
<?php
$str = <<<XML
<?xml version="1.0"?>
<!DOCTYPE doc [
<!ENTITY e SYSTEM "/tmp/exp">
]>
<tag>&e;</tag>
XML;
$xml = new SimpleXMLElement($str);
echo $xml;
?>
这应该打印出 /tmp/exp
的内容,但我不明白为什么,即使我 运行 使用 sudo
脚本或更改 /tmp/exp
文件权限 777
.
默认情况下禁用加载外部实体,因为它会导致 various security vulnerabilities。
要安全启用它,您需要register a custom entity loader,它可以检查预期的实体路径并决定是否加载它们。例如,您可能允许特定目录中的任何文件,但不允许磁盘上其他地方的任何文件 - 您可能不需要允许对 /etc/passwd
等系统文件的引用。或者,您可以将提供的路径映射到系统上完全不同的位置。
然后您还需要提供 the LIBXML_NOENT
option 来告诉解析器通过您的处理程序扩展实体。
例如:
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);
<?php
$str = <<<XML
<?xml version="1.0"?>
<!DOCTYPE doc [
<!ENTITY e SYSTEM "/tmp/exp">
]>
<tag>&e;</tag>
XML;
$xml = new SimpleXMLElement($str);
echo $xml;
?>
这应该打印出 /tmp/exp
的内容,但我不明白为什么,即使我 运行 使用 sudo
脚本或更改 /tmp/exp
文件权限 777
.
默认情况下禁用加载外部实体,因为它会导致 various security vulnerabilities。
要安全启用它,您需要register a custom entity loader,它可以检查预期的实体路径并决定是否加载它们。例如,您可能允许特定目录中的任何文件,但不允许磁盘上其他地方的任何文件 - 您可能不需要允许对 /etc/passwd
等系统文件的引用。或者,您可以将提供的路径映射到系统上完全不同的位置。
然后您还需要提供 the LIBXML_NOENT
option 来告诉解析器通过您的处理程序扩展实体。
例如:
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);