CodeQL 文档

XML 外部实体扩展

ID: py/xxe
Kind: path-problem
Security severity: 9.1
Severity: error
Precision: high
Tags:
   - security
   - external/cwe/cwe-611
   - external/cwe/cwe-827
Query suites:
   - python-code-scanning.qls
   - python-security-extended.qls
   - python-security-and-quality.qls

点击查看 CodeQL 仓库中的查询

使用配置较弱的 XML 解析器解析不受信任的 XML 文件可能会导致 XML 外部实体 (XXE) 攻击。这种类型的攻击使用外部实体引用来访问系统上的任意文件,执行拒绝服务 (DoS) 攻击或服务器端请求伪造。即使解析结果未返回给用户,DoS 攻击仍然可能发生,并且带外数据检索技术可能允许攻击者窃取敏感数据。

建议

防止 XXE 攻击的最简单方法是在解析不受信任的数据时禁用外部实体处理。如何做到这一点取决于所使用的库。请注意,某些库,例如 Python 3 标准库中最近版本的 XML 库,默认情况下会禁用实体扩展,因此除非您显式启用实体扩展,否则无需采取任何进一步的措施。

我们建议使用 defusedxml PyPI 包,该包旨在防止 XML 攻击(包括 XXE 和 XML 炸弹)。

示例

以下示例使用 lxml XML 解析器来解析字符串 xml_src。该字符串来自不受信任的来源,因此这段代码容易受到 XXE 攻击,因为来自 lxml.etree 默认解析器 允许解析本地外部实体。

from flask import Flask, request
import lxml.etree

app = Flask(__name__)

@app.post("/upload")
def upload():
    xml_src = request.get_data()
    doc = lxml.etree.fromstring(xml_src)
    return lxml.etree.tostring(doc)

为了防止使用 lxml 库进行 XXE 攻击,您应该创建一个解析器,将 resolve_entities 设置为 false。这意味着不会进行任何实体扩展,尽管仍然允许使用标准的预定义实体,例如 >,用于在 XML 元素文本中写入 >

from flask import Flask, request
import lxml.etree

app = Flask(__name__)

@app.post("/upload")
def upload():
    xml_src = request.get_data()
    parser = lxml.etree.XMLParser(resolve_entities=False)
    doc = lxml.etree.fromstring(xml_src, parser=parser)
    return lxml.etree.tostring(doc)

参考资料

  • ©2025GitHub, Inc.
  • 条款
  • 隐私