20.4. XML处理模块
*****************

**源码：** Lib/xml/

======================================================================

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

警告:

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

值得注意的是 "xml" 包中的模块要求至少有一个 SAX 兼容的 XML 解析器可用
。在 Pythonm中包含 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解析器绑定


20.4.1. XML 漏洞
================

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

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

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

1. Expat 2.4.1 and newer is not vulnerable to the "billion laughs" and
   "quadratic blowup" vulnerabilities. Items still listed as
   vulnerable due to potential reliance on system-provided libraries.
   Check "pyexpat.EXPAT_VERSION".

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

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

4. "xmlrpclib" 不扩展外部实体并省略它们。

5. Since Python 3.6.7, external general entities are no longer
   processed by default.

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 的文档包含有关所有已知攻击向量的更多信息以及示例和参
考。


20.4.2. "defusedxml" 和 "defusedexpat" 软件包
=============================================

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

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