在允许 DTD 加载之前检查是否存在恶意 XML?

2024-01-08

从 libxml 2.9 开始,解析 XML 时已禁用加载外部实体,以防止XXE 攻击 http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html.

在这种情况下,为了能够在使用 PHP 的 DOMDocument 解析 XML 时加载 DTD 文件,LIBXML_DTDLOAD必须指定。

有什么好方法来验证这一点only在启用之前将加载预期的 DTDLIBXML_DTDLOAD?

我能想到的一种方法(如下面的示例代码所示)是禁用实体加载,解析 XML 文件一次,检查 DOCTYPE 声明是否符合预期,然后在启用实体加载的情况下再次解析 XML。这样就足够了吗?

<?php

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.0 20120330//EN" "http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd">
<article/>
XML;

// entity loading disabled

libxml_disable_entity_loader();

$doc = new DOMDocument;
$doc->loadXML($xml, LIBXML_DTDLOAD); // PHP Warning:  DOMDocument::load(): I/O warning : failed to load external entity

print $doc->doctype->systemId; // http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd

// entity loading enabled

libxml_disable_entity_loader(false);

$doc = new DOMDocument;
$doc->loadXML($xml, LIBXML_DTDLOAD);

print $doc->doctype->systemId; // http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd

在启用之前验证是否仅加载预期的 DTD 的好方法是什么LIBXML_DTDLOAD?

如果您想过滤(白名单)预期的 DTD,您可以通过返回禁用所有其他 DTD 来实现NULL从你自己的callable已被设置为外部实体加载器 via libxml_set_external_entity_loader http://php.net/libxml_set_external_entity_loader.

也就是说,您将使用LIBXML_DTDLOAD标记,然后解析为资源句柄 http://php.net/fopen在您的函数中,以防 DTD 被列入白名单。如果没有,你返回说NULL http://php.net/null.

<?php
/**
 * @link http://stackoverflow.com/q/24526493/367456
 */

$xml = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.0 20120330//EN" "http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd">
<article/>
XML;

/* own entity loader */
libxml_set_external_entity_loader(function() {
  var_dump(func_get_args()); // just for demonstrating purposes
  return NULL;
});

$doc = new DOMDocument;
$doc->loadXML($xml, LIBXML_DTDLOAD);

echo "----\n";

/* restore default entity loader */    
libxml_set_external_entity_loader(NULL);

$doc = new DOMDocument;
$doc->loadXML($xml, LIBXML_DTDLOAD);

输出示例:

array(3) {
  [0]=>
  string(66) "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.0 20120330//EN"
  [1]=>
  string(66) "http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd"
  [2]=>
  array(4) {
    ["directory"]=>
    string(1) "/"
    ["intSubName"]=>
    string(7) "article"
    ["extSubURI"]=>
    string(66) "http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd"
    ["extSubSystem"]=>
    string(66) "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.0 20120330//EN"
  }
}

Warning: DOMDocument::loadXML(): Failed to load external entity "-//NLM//DTD JATS (Z39.96) Journal Publishing DTD v1.0 20120330//EN" in Entity, line: 2 in /in/jemmH on line 18
----

Warning: DOMDocument::loadXML(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /in/jemmH on line 25

Warning: DOMDocument::loadXML(http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd): failed to open stream: php_network_getaddresses: getaddrinfo failed: Name or service not known in /in/jemmH on line 25

Notice: DOMDocument::loadXML(): failed to load external entity "http://jats.nlm.nih.gov/publishing/1.0/JATS-journalpublishing1.dtd" in Entity, line: 2 in /in/jemmH on line 25
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在允许 DTD 加载之前检查是否存在恶意 XML? 的相关文章

  • PHP 或 WAMP 不确定是什么

    我已经安装了 WAMP 服务器 2 0 PHP 5 4 3 安装WAMP后我已经重新启动了所有服务并且可以打开 phpinfo 显示良好 phpmyadmin 它也显示得很好 我可以使用数据库 然而 当在 Chrome 中运行简单的 php
  • PHP 开发相当于 Mongrel/Webrick 吗?

    PHP 开发中是否有与 Rails 开发期间使用 Mongrel Webrick 等效的方法 我通常在端口 3000 上使用 Mongrel 在开发过程中为我的 Rails 应用程序提供服务 我从事 PHP 开发已经有几年了 据我所知 方法
  • 如何使用 Facebook SDK API 为页面/网址“点赞”?

    我正在使用这段代码 facebook gt api me likes post array url gt http www google com 我收到以下错误 Fatal error Uncaught OAuthException 200
  • 在字符串中间添加一个字符

    可能有一个简单的解决方案可以解决这个问题 但会引起面部表情 我将时间存储为 4 个字符长的字符串 即 1300 我试图将该字符串显示为 13 00 我觉得必须有一个比我现在正在做的更优雅的解决方案 我目前有 startTime get fi
  • 通过 facebook graph API 检索 facebook 用户的邮政编码

    我正在尝试使用 facebook graph API 检索用户的邮政编码 我正在使用以下代码 代码在php ini中 facebook new Facebook array appId gt APP ID secret gt APP SEC
  • 如何在 PHP 中使用 cURL 发出同时包含 GET 和 POST 参数的请求?

    其他人已经问过如何从 perl java bash 等执行此操作 但我需要在 PHP 中执行此操作 并且我没有看到任何已提出的专门与 PHP 相关的问题 或包含 PHP 的答案 My code ch curl init url curl s
  • PHP:读取字体文件的 TrueType/OpenType 元数据

    如何阅读字体详细信息 例如 字体在其元数据中包含版权 姓氏 设计者 版本等信息 我还希望脚本能够计算文件中的字形数量 并返回字体支持的语言 例如 典型的字体可能包含西方语言 瑞典语和罗马语言支持 并具有数百个字形 它应该支持 truetyp
  • Laravel 5 中的自定义验证器

    我正在将 Laravel 应用程序从 4 升级到 5 但是 我有一个自定义验证器 但无法运行 在L4中 我做了一个验证器 php文件并将其包含在全局 php using require app path validators php 我尝试
  • 语法错误,第 288 行出现意外的“endif”(T_ENDIF)[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我一直在离线处理我的 WordPress 网站的此代码错误 解析错误 语法错误 homez 541 photoher marie
  • 如何在 yii2 中使用两个不同的模型登录或切换身份类别?

    我想允许用户从两个不同的模型登录 配置文件 user gt identityClass gt app models User one more class here enableAutoLogin gt false authTimeout
  • 自动建议 php 的 ajax

    我有一个 html 表单 php 脚本和 jquery 我需要一个 ajax 代码来从我的 php 脚本中进行自动建议 以下是代码 表单 html
  • MySQL PHP邮政编码比较具体距离

    我试图找出比较一个邮政编码 用户提供的 和一大堆其他邮政编码 现在大约有 200 个邮政编码 之间的距离的最有效方法 相对于加载时间 但它会随着时间的推移而增加 我不需要任何精确的东西 只是在球场上 我下载了整个美国的邮政编码 csv 文件
  • 如何仅使用 PHP5 RecursiveDirectoryIterator 类递归显示具有特定文件类型的文件夹和子文件夹

    您好 我正在尝试使用 FilterIterator 上的扩展来获取 RecursiveDirectoryIterator 类 但由于某种原因 它仅在根目录上进行迭代 我的代码是这样的 class fileTypeFilter extends
  • MVC 模式中的验证层

    验证模型将使用的数据的最佳位置在哪里 例如 考虑登记表 我们有一些来自注册表的数据 那么验证这些数据的最佳位置在哪里 我们应该通过 if 语句或特殊的验证器类来检查每个数据 这意味着大量的编码 所以我想了解在哪里可以做到这一点 在控制器中
  • 检查条件并通过 Zend 中的 Regex 识别 url 中的模式

    我正在实现 Zend Regex 路由 并且必须对 url 执行多次检查 例如 如果这是我的网址 http localhost application public index php module controller action 这是
  • 从数据库填充复选框

    我有两个表 第一个由与名称关联的 id 组成 1 汽车 2 火车 3 普通 ETC 第二个表由两个字段 user id 和第一个表中的 id 组成 例如 1 1 2 1 3 当用户转到该页面时 我试图重新填充选定的复选框 首先 您查询数据库
  • 如何在 Zend Framework 3 中注册自定义表单视图助手

    我正在将继承的 Zend Framework 2 应用程序迁移到 Zend Framework 3 并且在注册自定义表单视图助手时遇到了一些困难 这些助手在应用程序使用版本 2 时起作用 主要用于添加标签属性以实现可访问性 例如 这是一个自
  • XSD 嵌套元素

  • 如何从父类中获取子类名

    我试图在不需要子类上的函数的情况下完成此任务 这可能吗 我有一种感觉 但我真的很想确定
  • php 数组中出现意外的 json 输出结构

    我正在尝试转换动态数据 如何从 PHP 获取此 JSON JSON 122240cb 253c 4046 adcd ae81266709a6 item 0 3 这就是我所做的 但它不起作用 PHP json array 122240cb 2

随机推荐

  • Xcode 8 / Swift 3:didSelectRowAt 与 didSelectRowAtIndexPath

    在我们的 Swift 3 迁移之后 发生了一些非常奇怪的事情 我们有两个视图控制器 它们都实现UITableViewDelegate并且他们都实现了public func tableView tableView UITableView di
  • 如何升级使用ORM工具构建的数据库架构?

    我正在寻找使用 ORM 工具 例如 JPOX 或 Hibernate 升级数据库架构的通用解决方案 您在项目中是如何做到的 我想到的第一个解决方案是创建自己的数据库升级机制 并使用 SQL 脚本完成所有工作 但在这种情况下 我必须记住每次更
  • 有没有办法从表中的 OLEObject 字段中提取 AutoCAD 绘图和图片?

    仅提供一些背景信息 我是一家公司的机械工程师 这里的前辈在 Access 2003 中创建了一个数据库 该数据库基本上采用 AutoCAD 绘图或图片 OLE 并将其与一堆其他信息一起放入一个精美的框架报告中 我一直在对该数据库进行一些修改
  • 删除或更改 UIWebView 文档显示周围的框架颜色?

    我正在使用一个UIWebView显示嵌入到主视图中的各种文件类型 因此我无法使用专门的 PDF 查看器 因此我无法使用模式文档交互控制器 我的主视图的背景设计与出现在文档周围的浅灰色框架相冲突 UIWebView 有谁知道如何去除灰色框架
  • 除了 LINQ 查询之外,如何在 C# 中使用匿名类型?

    我一直在尝试快速了解 C 中的一些新功能 其中我还没有机会使用的功能之一是匿名类型 我了解与 LINQ 查询相关的用法 并且我查看了这个帖子 https stackoverflow com questions 48668 how shoul
  • Facebook 字符串没有默认翻译

    我今天尝试运行附加了 Facebook SDK 的应用程序时遇到此错误 Warning string com facebook smart login confirmation continue as f1gender has no def
  • .NET 中的反向排序字典

    有什么方法可以在 C 中向后 反向 迭代 SortedDictionary 吗 或者有没有办法首先按降序定义 SortedDictionary SortedDictionary 本身不支持向后迭代 但您有多种可能性来实现相同的效果 Use
  • Javascript 正则表达式模式将多个字符串( AND、OR )与单个字符串进行匹配

    我需要根据相当复杂的查询过滤字符串集合 在它的 原始 形式中 它看起来像这样 nano AND regulat OR toxic OR risk OR hazard AND exposure OR release 要匹配的字符串之一的示例
  • Dagger2 没有完全解决依赖关系

    我有一个 MainActivity 它注入 Presenter presenter 对象注入交互器 交互器对象注入 APIHelper 所有 Presenter Interactor 和 APIHelper 的提供者都在 MainModul
  • Heroku 上奇怪的 TTFB(第一个字节的时间)问题

    我们正在改进 Heroku 上托管的 Rails 应用程序 rails 3 2 8 和 ruby 1 9 3 的性能 在此期间 我们遇到了一个令人震惊的问题 其来源似乎极难追踪 让我快速解释一下我们如何遇到这个问题以及我们如何尝试隔离它 自
  • 如何测试纬度/经度点是否在地图内(不是谷歌地图)

    如果我有一个类定义了一个地图 其顶部 左侧由经度和纬度定义 底部 右侧也由经度和纬度定义 如何测试给定的纬度 经度是否在地图的边界点内 这不是一个与谷歌地图有关的问题 例如 奥兰多是在覆盖塔哈斯到迈阿密的地图内 公共类 MapContext
  • 如何滚动 QListWidget 到所选项目

    下面的代码创建一个对话框窗口QListWidget and QPushButton 单击按钮会启动scroll 查找并选择 ITEM 0011 的函数 我想知道是否有一种方法可以滚动列表小部件 以便选定ITEM 0011位于顶部边缘QLis
  • C#:左移赋值运算符行为

    我正在运行的代码有时会产生以下结果 UInt32 current int left right sometimes left right and no shift occurs current lt lt 32 left right thi
  • 在git中合并package.json(解决版本冲突)

    我们不断收到 package json 中版本字段的冲突 例如 version 1 1 144 and version 1 1 145 有没有办法用最高版本号自动解决 最终写了一个npm 包 https www npmjs com pack
  • 如何停用鸡蛋?

    我已经 反复 安装了 cx Oracle 但无法让它在我的 Intel Mac 上运行 如何停用 卸载它 您只需删除 egg file 在 OS X 上 它们被安装到 Library Python 2 5 site packages 在该文
  • 为什么 Spring 在一台机器上出现循环依赖问题,而在另一台机器上却没有?

    我在获取基于 Spring Data 的应用程序在我的环境中运行时遇到问题 我运行的是 Debian 但我的同事使用的是 Mac 或 Ubuntu 我的环境变量中没有任何特殊设置 并且使用与其他人完全相同的 Java 版本 我在日志中看到了
  • 关于集成测试类的 Spring 配置文件

    我们有由 java 测试类运行的 selenium 测试 在本地环境中一切正常 但我想在詹金斯上运行时关闭这些测试 所以我用 RunWith SpringJUnit4ClassRunner class SpringApplicationCo
  • JSON 中的单引号与双引号

    My code import simplejson as json s username dfdsfdsf 1 s username dfdsfdsf 2 j json loads s 1定义是错误的 2定义是正确的 我听说在Python中
  • MySQL:删除所有超过 20 小时的行

    我的表中有一个时间戳字段 如何删除超过 20 小时的记录 我的查询是 DELETE FROM tickets WHERE timestamp lt NOW INTERVAL 20 HOUR 问题 以上查询是否正确 是的 你的delete查询
  • 在允许 DTD 加载之前检查是否存在恶意 XML?

    从 libxml 2 9 开始 解析 XML 时已禁用加载外部实体 以防止XXE 攻击 http websec io 2012 08 27 Preventing XEE in PHP html 在这种情况下 为了能够在使用 PHP 的 DO