Python如何安全地解析不可信的XML DefusedXML

20次阅读

必须使用defusedxml替代标准库xml模块,因其默认禁用外部实体、限制嵌套深度(100层)、字符数(10MB)等,防止XXE、billion laughs等攻击;标准库默认启用外部实体且无资源限制,易导致RCE或DoS。

Python如何安全地解析不可信的XML DefusedXML

python解析不可信XML时,必须防止XXE(XML外部实体)攻击、 billion laughs 攻击、以及递归实体展开等安全风险。DefusedXML 是专为解决这些问题设计的库,它通过禁用危险特性、设置严格解析限制,来替代 Python 标准库中不安全的 xml 模块。

为什么不能直接用标准库的 xml.etree.ElementTree?

Python 原生的 xml.etree.ElementTreexml.dom.minidomxml.sax 默认启用外部实体解析,且不限制嵌套深度或实体展开数量。攻击者可构造恶意 XML,导致拒绝服务(内存耗尽、CPU 占满)甚至读取本地文件(如 file:///etc/passwd)。

用 defusedxml 替换标准解析器(推荐做法)

安装后,用对应模块直接替换原生导入,无需修改业务逻辑:

# 安装
pip install defusedxml

立即学习Python免费学习笔记(深入)”;

# 替换示例(ElementTree 场景)
# ❌ 不安全
from xml.etree.ElementTree import fromstring

# ✅ 安全替换
from defusedxml.ElementTree import fromstring

Python如何安全地解析不可信的XML DefusedXML

PHP5 和 MySQL 圣经

本书是全面讲述PHP与MySQL的经典之作,书中不但全面介绍了两种技术的核心特性,还讲解了如何高效地结合这两种技术构建健壮的数据驱动的应用程序。本书涵盖了两种技术新版本中出现的最新特性,书中大量实际的示例和深入的分析均来自于作者在这方面多年的专业经验,可用于解决开发者在实际中所面临的各种挑战。

Python如何安全地解析不可信的XML DefusedXML 485

查看详情 Python如何安全地解析不可信的XML DefusedXML

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
  • 限制 XML 嵌套深度(默认 100 层),防止溢出
  • 限制总字符数(默认 10MB)、属性数量、命名空间数量等
  • 禁用 DTD 解析(除非显式启用且受控)
  • 对重复实体展开做计数限制,防御 billion laughs 类型攻击

进阶:自定义限制与显式控制

若需微调策略(例如允许极小范围的内部实体),可通过参数传入限制配置:

# 示例:放宽单次解析最大字符数到 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_entitiesforbid_dtd=False;绝大多数 Web API 场景应保持默认最严策略。

text=ZqhQzanResources