19.5. XML 处理模块

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

Warning

XML 模块对于错误或恶意构建的数据并不安全。如果您需要解析不可信或未经身份验证的数据,请参见XML vulnerabilities

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

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

XML 处理子模块是:

19.6. XML 漏洞

XML 处理模块不能防止恶意构建的数据。攻击者可以滥用漏洞,例如拒绝服务攻击,访问本地文件,与其他计算机或与防火墙的网络连接。对 XML 滥用的攻击是不熟悉的Function,例如带有实体的内联DTD(文档类型定义)。

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

kindsaxetreeminidompulldomxmlrpc
billion laughsVulnerableVulnerableVulnerableVulnerableVulnerable
quadratic blowupVulnerableVulnerableVulnerableVulnerableVulnerable
外部实体扩张VulnerableSafe (1)Safe (2)VulnerableSafe (3)
DTD retrievalVulnerableSafeSafeVulnerableSafe
decompression bombSafeSafeSafeSafeVulnerable
  • xml.etree.ElementTree不会展开外部实体,并且在发生实体时会引发 ParserError。

  • xml.dom.minidom不会展开外部实体,而只会逐字返回未展开的实体。

  • xmlrpclib不会扩展外部实体并忽略它们。

  • 十亿笑声/指数实体扩张

    • Billion Laughs攻击(也称为指数实体扩展)使用多层嵌套实体。每个实体多次引用另一个实体,finally实体定义包含一个小字符串。finally,小字符串扩展到了几 GB。指数级扩展也消耗大量的 CPU 时间。
  • 二次爆炸实体扩展

    • 二次爆炸攻击类似于Billion Laughs攻击;它也滥用实体扩张。而不是嵌套实体,它一遍又一遍地重复一个带有几千个字符的大型实体。攻击的效率不及指数级情况,但可以避免针对大量嵌套的实体触发解析器的对策。
  • 外部实体扩张

    • 实体语句可以包含的内容不止是要替换的文本。它们还可以pass公共标识符或系统标识符指向外部资源。系统标识符是标准 URI 或可以引用本地文件。 XML 解析器使用来检索资源。 HTTP 或 FTP 请求并将内容嵌入到 XML 文档中。
  • DTD retrieval

    • 一些 XML 库(例如 Python 的xml.dom.pulldom)从远程或本地位置检索文档类型定义。该Function与外部实体扩展问题具有相似的含义。
  • decompression bomb

    • 减压炸弹(也称为ZIP bomb)问题适用于所有 XML 库,这些库可以解析压缩的 XML 流,例如压缩的 HTTP 流或 LZMA 版本的文件。对于攻击者而言,它可以将传输的数据量减少三个数量级或更多。

有关 PyPI 的defusedxml的文档提供了有关所有已知攻击媒介的更多信息,并提供了示例和参考。

19.6.1. 拆包

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

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

defusedexpat提供了经过修改的 libexpat 和修补后的替换pyexpat扩展模块,具有针对实体扩展 DoS 攻击的对策。 Defusedexpat 仍然允许合理且可配置的实体扩展量。这些修改将合并到将来的 Python 版本中。

解决方法和修改不包含在补丁程序发行版中,因为它们破坏了向后兼容性。毕竟,内联 DTD 和实体扩展都是定义明确的 XML Function。