在Python开发中,处理外部传入的XML数据是常见场景,比如接口对接、配置文件读取、数据导入等。但Python标准库中的xml模块默认开启了很多危险特性,解析不可信的XML时很容易触发XXE注入、递归实体展开导致的DoS攻击等安全问题,DefusedXML库就是专门用来解决这类问题的安全解析方案。

原生XML解析的安全风险
Python的xml.etree.ElementTree、xml.dom.minidom等标准库解析器,默认允许解析外部实体、参数实体,也没有限制实体展开的深度和大小,攻击者可以构造恶意XML实现多种攻击:
- XXE注入:读取服务器本地文件、发起内网请求,泄露敏感信息
- DoS攻击:构造递归实体让解析器无限展开,耗尽服务器CPU和内存
- SSRF攻击:通过外部实体请求内网服务,探测内网结构
比如下面这段恶意XML,使用原生解析器解析就会读取服务器/etc/passwd文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE foo [ <!ENTITY xxe SYSTEM "file:///etc/passwd"> ]> <foo>&xxe;</foo>
DefusedXML的核心防护机制
DefusedXML是对Python标准库XML解析模块的封装,它在不改变原有API使用习惯的前提下,默认禁用了所有危险特性:
- 禁止解析外部通用实体和参数实体
- 限制实体展开的最大深度和总数量
- 禁用DTD的加载和解析
- 限制解析的XML最大大小,避免大文件导致的资源耗尽
它提供了和原生库完全一致的API,开发者只需要替换导入的模块,不需要修改原有解析逻辑就能获得安全防护。
DefusedXML的安装与基本使用
安装方法
使用pip可以直接安装DefusedXML:
pip install defusedxml
替换原生解析器示例
原本使用xml.etree.ElementTree解析XML的代码,只需要修改导入部分:
# 原代码
# import xml.etree.ElementTree as ET
# 修改后代码
from defusedxml import ElementTree as ET
# 解析不可信的XML字符串
untrusted_xml = """<?xml version="1.0"?>
<user>
<name>test</name>
<age>20</age>
</user>"""
try:
root = ET.fromstring(untrusted_xml)
print("用户名:", root.find("name").text)
print("年龄:", root.find("age").text)
except Exception as e:
print("解析失败:", e)
上面的代码即使传入前面提到的恶意XXE XML,也会直接抛出异常,不会执行危险操作。
DefusedXML支持的常见解析模块
DefusedXML覆盖了Python中常用的XML解析场景,对应的替换模块如下:
| 原生模块 | DefusedXML对应模块 | 适用场景 |
|---|---|---|
| xml.etree.ElementTree | defusedxml.ElementTree | 轻量级XML解析,获取节点树 |
| xml.dom.minidom | defusedxml.minidom | DOM方式解析XML,需要随机访问节点 |
| xml.sax | defusedxml.sax | 流式解析大XML文件,事件驱动模式 |
| xml.dom.pulldom | defusedxml.pulldom | 拉式DOM解析,兼顾DOM和SAX的特性 |
| lxml.etree | defusedxml.lxml | 使用lxml库的场景,需要高性能解析 |
自定义安全配置
如果业务需要部分开启某些特性,可以通过参数自定义安全限制,比如调整最大实体展开次数:
from defusedxml.ElementTree import fromstring, DefusedXmlException
import defusedxml.ElementTree as ET
# 自定义最大实体展开次数为100,默认是50000
ET.DefusedXmlParser.max_entity_expansions = 100
xml_data = "<root><item>1</item></root>"
try:
root = fromstring(xml_data)
print("解析成功")
except DefusedXmlException as e:
print("触发安全限制:", e)
注意事项
- DefusedXML只负责解析阶段的安全,解析完成后的XML数据处理逻辑还需要开发者自行保证安全,比如对节点内容进行过滤、校验
- 不要同时导入原生xml模块和DefusedXML模块,避免误调用原生解析器导致安全漏洞
- 定期更新DefusedXML版本,及时获取新的安全补丁
安全解析不可信XML是开发中的基础要求,DefusedXML用极低的迁移成本就能规避原生解析器的大部分安全风险,建议在所有涉及不可信XML解析的场景中优先使用。
除了使用DefusedXML,也可以考虑对传入的XML做前置校验,比如检查是否包含DOCTYPE声明,提前拦截恶意XML,进一步提升安全性。
PythonDefusedXMLXML解析安全解析修改时间:2026-07-01 08:51:36