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);