20.4. XML处理模块¶
源代码: Lib/xml/
Python的用于处理XML的接口被分组在 xml
包中。
警告
XML模块对于错误或恶意构造的数据是不安全的。如果需要解析不受信任或未经认证的数据,请参阅 XML漏洞 和 defusedxml 和 defusedexpat 包 部分。
需要注意的是,xml
包中的模块要求至少有一个符合SAX的XML解析器可用。 Expat解析器包含在Python中,因此 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 |
---|---|---|---|---|---|
十亿笑 |
脆弱 |
脆弱 |
脆弱 |
脆弱 |
脆弱 |
二次爆炸 |
脆弱 |
脆弱 |
脆弱 |
脆弱 |
脆弱 |
外部实体扩展 |
脆弱 |
安全(1) |
安全(2) |
脆弱 |
安全(3) |
DTD 检索 |
脆弱 |
安全 |
安全 |
脆弱 |
安全 |
减压炸弹 |
安全 |
安全 |
安全 |
安全 |
脆弱 |
xml.etree.ElementTree
不扩展外部实体,并在实体发生时引发ParserError
。xml.dom.minidom
不扩展外部实体,并简单地返回未展开的实体。xmlrpclib
不扩展外部实体并省略它们。
- 十亿笑/指数实体扩张
Billion Laughs 攻击(也称为指数实体扩展)使用多级嵌套实体。每个实体多次引用另一个实体,最终实体定义包含一个小字符串。指数扩展导致几吉字节的文本,并消耗大量的内存和CPU时间。
- 二次膨胀实体膨胀
二次爆发攻击类似于 Billion Laughs 攻击;它也滥用实体扩张。而不是嵌套的实体,它重复一个大型实体与几千个字符一遍又一遍。攻击不如指数情况那么有效,但是它避免触发解析深度嵌套实体的解析器对策。
- 外部实体扩展
实体声明可以包含多个替换的文本。它们还可以指向外部资源或本地文件。 XML解析器访问资源并将内容嵌入到XML文档中。
- DTD 检索
一些XML库(如Python的
xml.dom.pulldom
)从远程或本地位置检索文档类型定义。该特征具有与外部实体扩展问题类似的影响。- 减压炸弹
解压缩炸弹(也称为 ZIP bomb)适用于所有可以解析压缩XML流的XML库,例如gzip压缩的HTTP流或LZMA压缩的文件。对于攻击者,它可以将传输的数据量减少三个数量级或更多。
关于PyPI的 defusedxml 的文档具有关于所有已知的具有示例和参考的攻击矢量的进一步的信息。
20.4.2. defusedxml
和 defusedexpat
包¶
defusedxml 是一个纯Python包,其中包含所有stdlib XML解析器的已修改子类,可防止任何潜在的恶意操作。对于解析不受信任的XML数据的任何服务器代码,建议使用此程序包。该包还附带了有关更多XML攻击(例如XPath注入)的示例漏洞和扩展文档。
defusedexpat 提供了修改的libexpat和修补的 pyexpat
模块,它们具有针对实体扩展DoS攻击的对策。 defusedexpat
模块仍然允许固定和可配置的实体扩展量。这些修改可能会包含在一些未来的Python版本中,但不会包含在任何Python修补程序版本中,因为它们会破坏向后兼容性。