# XML 處理模組

源码： Lib/xml/

用于处理XML的Python接口分组在 `xml` 包中。

警告

XML 模块对于错误或恶意构造的数据是不安全的。 如果需要解析不受信任或未经身份验证的数据，请参阅 XML 漏洞 和 defusedxml 和 defusedexpat 软件包 部分。

值得注意的是 `xml` 包中的模块要求至少有一个 SAX 兼容的 XML 解析器可用。在 Python 中包含 Expat 解析器，因此 `xml.parsers.expat` 模块将始终可用。

`xml.dom` 和 `xml.sax` 包的文档是 DOM 和 SAX 接口的 Python 绑定的定义。

XML 处理子模块包括:

- `xml.etree.ElementTree`： ElementTree API，一个简单而轻量级的XML处理器

- `xml.dom`：DOM API 定义

- `xml.dom.minidom`：最小的 DOM 实现

- `xml.dom.pulldom`：支持构建部分 DOM 树

- `xml.sax`：SAX2 基类和便利函数

- `xml.parsers.expat`：Expat解析器绑定

## XML 漏洞

XML 处理模块对于恶意构造的数据是不安全的。 攻击者可能滥用 XML 功能来执行拒绝服务攻击、访问本地文件、生成与其它计算机的网络连接或绕过防火墙。

下表概述了已知的攻击以及各种模块是否容易受到攻击。

种类 | sax | etree | minidom | pulldom | xmlrpc
--- | --- | --- | --- | --- | ---
billion laughs | 易受攻击 | 易受攻击 | 易受攻击 | 易受攻击 | 易受攻击
quadratic blowup | 易受攻击 | 易受攻击 | 易受攻击 | 易受攻击 | 易受攻击
external entity expansion | 安全 (4) | 安全 (1) | 安全 (2) | 安全 (4) | 安全 (3)
DTD retrieval | 安全 (4) | 安全 | 安全 | 安全 (4) | 安全
decompression bomb | 安全 | 安全 | 安全 | 安全 | 易受攻击

1. `xml.etree.ElementTree` 不会扩展外部实体并在实体发生时引发 `ParserError`。

2. `xml.dom.minidom` 不会扩展外部实体，只是简单地返回未扩展的实体。

3. `xmlrpclib` 不扩展外部实体并省略它们。

4. 从 Python 3.7.1 开始，默认情况下不再处理外部通用实体。

billion laughs / exponential entity expansion （狂笑/递归实体扩展）

  Billion Laughs 攻击 -- 也称为递归实体扩展 -- 使用多级嵌套实体。 每个实体多次引用另一个实体，最终实体定义包含一个小字符串。 指数级扩展导致几千 GB 的文本，并消耗大量内存和 CPU 时间。

quadratic blowup entity expansion（二次爆炸实体扩展）

  二次爆炸攻击类似于 Billion Laughs 攻击，它也滥用实体扩展。 它不是嵌套实体，而是一遍又一遍地重复一个具有几千个字符的大型实体。攻击不如递归情况有效，但它避免触发禁止深度嵌套实体的解析器对策。

external entity expansion

  实体声明可以包含的不仅仅是替换文本。 它们还可以指向外部资源或本地文件。 XML 解析器访问资源并将内容嵌入到 XML 文档中。

DTD retrieval

  Python 的一些 XML 库 `xml.dom.pulldom` 从远程或本地位置检索文档类型定义。 该功能与外部实体扩展问题具有相似的含义。

decompression bomb

  Decompression bombs（解压炸弹，又名 ZIP bomb）适用于所有可以解析压缩 XML 流（例如 gzip 压缩的 HTTP 流或 LZMA 压缩的文件）的 XML 库。 对于攻击者来说，它可以将传输的数据量减少三个量级或更多。

PyPI上 defusedxml 的文档包含有关所有已知攻击向量的更多信息以及示例和参考。

## `defusedxml` 和 `defusedexpat` 软件包

defusedxml 是一个纯 Python 软件包，它修改了所有标准库 XML 解析器的子类，可以防止任何潜在的恶意操作。 对于解析不受信任的XML数据的任何服务器代码，建议使用此程序包。 该软件包还提供了有关更多 XML 漏洞（如 XPath 注入）的示例漏洞和扩展文档。

defusedexpat 提供了一个修改过的 libexpat 和一个打过补丁的 `pyexpat` 模块，它有针对实体扩展DoS攻击的对策。 `defusedexpat` 模块仍然允许合理且可配置的实体扩展量。 这些修改可能包含在 Python 的某些未来版本中，但不会包含在 Python 的任何修复版本中，因为它们会破坏向后兼容性。