XML <!ENTITY e SYSTEM "/path/to/file"> 不适用于 PHP SimpleXMLElement
Posted
技术标签:
【中文标题】XML <!ENTITY e SYSTEM "/path/to/file"> 不适用于 PHP SimpleXMLElement【英文标题】:XML <!ENTITY e SYSTEM "/path/to/file"> does not work with PHP SimpleXMLElement 【发布时间】:2022-01-03 18:53:41 【问题描述】:<?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
。
【问题讨论】:
尝试将LIBXML_NOENT
作为第二个参数传递给构造函数:3v4l.org/nTvDp
@ChrisHaas 成功了,谢谢!
@ChrisHaas 在推荐打开该选项之前,您应该了解为什么它默认不打开:它已涉及许多安全漏洞,因此需要谨慎使用。
@IMSoP,我 100% 同意,但似乎这也可能是 OP 的目的。
@ChrisHaas 不一定;显然,我的答案中的示例是一个不切实际的严格过滤器,但关键是您可以拥有一个可以从何处加载实体的白名单 - 例如加载/etc/passwd
不太可能是合法用途
【参考方案1】:
默认情况下禁用加载外部实体,因为它可能导致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);
【讨论】:
以上是关于XML <!ENTITY e SYSTEM "/path/to/file"> 不适用于 PHP SimpleXMLElement的主要内容,如果未能解决你的问题,请参考以下文章
MVC开发中的常见错误-03-System.Data.Entity.Validation.DbEntityValidationException: 对一个或多个实体的验证失败。有关详细信息,请参见“E
方法 System.Data.Entity.ModelConfiguration.EntityTypeConfiguration<Proyect.Models.Entity>.HasMan
DOMDocument::loadXML(): AttValue: " or ' expected in Entity, line: 报错