You need to enable JavaScript to run this app. 不使用lxml的resolve_entities选项实现XML实体解析
优惠活动
大模型
产品
解决方案
定价
更多

不使用lxml的resolve_entities选项实现XML实体解析

不开启resolve_entities完成XML实体解析的方案

RSPEC-2755是Sonar针对XML外部实体注入(XXE)风险的检测规则,直接开启resolve_entities=True会允许解析任意外部实体,确实存在安全隐患。你可以通过以下两种方案在不开启该配置的前提下完成实体解析:


方案1:自定义可信实体解析器

lxml支持自定义实体解析回调,你可以仅放行预设的可信实体,完全不需要开启全局的实体解析开关。
实现步骤:

  • 保持XMLParser的resolve_entities为默认值False
  • 继承lxml.etree.EntityResolver类,实现resolve方法,仅返回你允许解析的实体内容
  • 将自定义解析器实例添加到parser的resolvers列表中
    代码示例:
from lxml import etree

# 自定义仅处理可信实体的解析器
class CustomEntityResolver(etree.EntityResolver):
    def resolve(self, system_id, public_id, context):
        # 示例:仅处理白名单内的实体定义
        if system_id == "trusted_entity.dtd":
            # 返回预设的合法实体定义内容
            return self.resolve_string('<!ENTITY custom_entity "预设的实体内容">', context)
        # 非白名单实体直接跳过解析
        return None

# 初始化parser,默认不开启resolve_entities
parser = etree.XMLParser()
# 注册自定义解析器
parser.resolvers.add(CustomEntityResolver())

# 解析XML文件
xml_tree = etree.parse("your_target.xml", parser=parser)

方案2:预替换内部实体

如果你的XML仅包含内部实体,没有外部实体引用,可以先做实体替换再解析:

  • 读取XML原始文本,通过正则提取所有<!ENTITY 实体名 "实体值">格式的内部实体定义,存储为键值对映射表
  • 遍历XML文本,把所有&实体名;格式的引用替换为映射表对应的实体值
  • 用默认parser直接解析替换后的XML文本

注意:该方案仅适用于仅含内部实体的场景,不要用于处理未知来源的外部实体引用,避免引入注入风险。


安全提示

无论使用哪种方案,都要严格限制可解析的实体范围,不要开放任意实体的解析权限,避免触发XXE安全漏洞。如果需要处理外部实体,必须对资源来源做白名单校验,仅加载可信域名下的资源。

内容的提问来源于stack exchange,提问作者Ankit Varshney

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 15:15:05