19.5. XML 处理模块 — Python 文档

来自菜鸟教程
Python/docs/2.7/library/xml
跳转至:导航、​搜索

19.5. XML 处理模块

Python 处理 XML 的接口被分组在 xml 包中。

警告

XML 模块对于错误或恶意构造的数据并不安全。 如果您需要解析不受信任或未经身份验证的数据,请参阅 XML 漏洞


需要注意的是,xml 包中的模块要求至少有一个符合 SAX 的 XML 解析器可用。 Expat 解析器包含在 Python 中,因此 xml.parsers.expat 模块将始终可用。

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

XML 处理子模块是:


19.6. XML 漏洞

XML 处理模块对于恶意构造的数据并不安全。 攻击者可以滥用漏洞,例如 拒绝服务攻击、访问本地文件、生成与其他机器的网络连接、或绕过防火墙。 对 XML 的攻击滥用了不熟悉的特性,例如与实体内联 DTD(文档类型定义)。

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

种类 萨克斯 迷你世界 拉力 xmlrpc
十亿笑声 易受伤害的 易受伤害的 易受伤害的 易受伤害的 易受伤害的
二次爆发 易受伤害的 易受伤害的 易受伤害的 易受伤害的 易受伤害的
外部实体扩展 易受伤害的 保险箱 (1) 保险箱 (2) 易受伤害的 保险箱 (3)
DTD检索 易受伤害的 安全的 安全的 易受伤害的 安全的
减压炸弹 安全的 安全的 安全的 安全的 易受伤害的
  1. xml.etree.ElementTree 不扩展外部实体并在实体发生时引发 ParserError。
  2. xml.dom.minidom 不扩展外部实体,只是逐字返回未扩展的实体。
  3. xmlrpclib 不扩展外部实体并省略它们。
十亿笑/指数实体扩张
Billion Laughs 攻击(也称为指数实体扩展)使用多层嵌套实体。 每个实体多次引用另一个实体,最终的实体定义包含一个小字符串。 最终,小字符串会扩展到几 GB。 指数扩展也会消耗大量 CPU 时间。
二次膨胀实体扩展
二次爆发攻击类似于 亿笑 攻击; 它也滥用实体扩展。 它不是嵌套实体,而是一遍又一遍地重复一个包含数千个字符的大型实体。 这种攻击不如指数情况那么有效,但它避免了针对严重嵌套实体触发解析器的对策。
外部实体扩展
实体声明可以包含的不仅仅是用于替换的文本。 它们还可以通过公共标识符或系统标识符指向外部资源。 系统标识符是标准 URI 或可以引用本地文件。 XML 解析器使用例如检索资源 HTTP 或 FTP 请求并将内容嵌入到 XML 文档中。
DTD检索
一些 XML 库,如 Python 的 xml.dom.pulldom 从远程或本地位置检索文档类型定义。 该功能与外部实体扩展问题具有类似的含义。
减压炸弹
解压炸弹(又名 ZIP 炸弹)的问题适用于所有可以解析压缩的 XML 流的 XML 库,如 gzipped HTTP 流或 LZMA-ed 文件。 对于攻击者来说,它可以将传输的数据量减少三个或更多。

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

19.6.1. 拆包

建议将这些外部包用于解析不受信任的 XML 数据的任何代码。

defusedxml 是一个纯 Python 包,它修改了所有 stdlib XML 解析器的子类,以防止任何潜在的恶意操作。 该软件包还附带示例漏洞利用和有关更多 XML 漏洞利用(如 xpath 注入)的扩展文档。

defusedexpat 提供了一个修改的 libexpat 和补丁替换 pyexpat 扩展模块,以对抗实体扩展 DoS 攻击。 Defusedexpat 仍然允许合理且可配置的实体扩展量。 这些修改将合并到 Python 的未来版本中。

变通方法和修改不包含在补丁版本中,因为它们破坏了向后兼容性。 毕竟内联 DTD 和实体扩展是定义良好的 XML 特性。