必须使用defusedxml替代标准库xml模块,因其默认禁用外部实体、限制嵌套深度(100层)、字符数(10MB)等,防止XXE、billion laughs等攻击;标准库默认启用外部实体且无资源限制,易导致RCE或DoS。
Python解析不可信XML时,必须防止XXE(XML外部实体)攻击、 billion l
aughs 攻击、以及递归实体展开等安全风险。DefusedXML 是专为解决这些问题设计的库,它通过禁用危险特性、设置严格解析限制,来替代 Python 标准库中不安全的 xml 模块。
Python 原生的 xml.etree.ElementTree、xml.dom.minidom 和 xml.sax 默认启用外部实体解析,且不限制嵌套深度或实体展开数量。攻击者可构造恶意 XML,导致拒绝服务(内存耗尽、CPU 占满)甚至读取本地文件(如 file:///etc/passwd)。
安装后,用对应模块直接替换原生导入,无需修改业务逻辑:
# 安装
pip install defusedxml
# 替换示例(ElementTree 场景)
# ❌ 不安全
from xml.etree.ElementTree import fromstring
# ✅ 安全替换
from defusedxml.ElementTree import fromstring
defusedxml 提供了与标准库完全兼容的封装模块:
defusedxml.ElementTree → 替代 xml.etree.ElementTree
defusedxml.minidom → 替代 xml.dom.minidom
defusedxml.pulldom → 替代 xml.dom.pulldom
defusedxml.sax → 替代 xml.sax
defusedxml.expat → 替代 xml.parsers.expat
defusedxml 在底层禁用了高危功能,并设定了保守的资源上限:
resolve_entities=False),杜绝 XXE若需微调策略(例如允许极小范围的内部实体),可通过参数传入限制配置:
# 示例:放宽单次解析最大字符数到 50MB,但依然禁用外部实体
from defusedxml.ElementTree import parse
parser = defusedxml.ElementTree.XMLParser(
resolve_entities=False,
forbid_dtd=False, # 仅当真需要 DTD 时才设 True
forbid_entities=True, # 推荐保持 True
max_entity_expansions=1000,
max_xml_size=50_000_000
)
tree = parse("untrusted.xml", parser)
注意:除非明确了解风险,否则不要启用 resolve_entities 或 forbid_dtd=False;绝大多数 Web API 场景应保持默认最严策略。