FlawOpen

flawopen.com/Teardowns/cve-2026-105751-docling-odf-file-disclosure

● CVE-2026-105751 · CVSS v4 6.9 · 中危
安全研究 · FlawOpen

CVE-2026-105751:Docling ODF 文件泄露

Docling 的 ODF 后端可能把文档中的图像引用当作本地路径,并读取归档之外的文件。请升级到 2.120.3;修复通过共享资源控制组件加载资源。

CVSS 向量CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N
💡 通俗易懂的原理解析 (ELI5)

图书管理员先在相册里找照片。如果找不到,有缺陷的读取器就按相册标签上的路径去文件柜打开文件,却不检查图书馆禁止读取本地文件的规则。修复让它改用其他文档格式共用的受控资源柜台。

核心概念与专有名词

OpenDocument Format (ODF)
一种办公文档格式系列,包含 .odt 文本文档。Docling 从文档 XML 中读取图像引用。
draw:image
描述图像的 ODF XML 元素;其 xlink:href 值标识资源。
xlink:href
ODF 图像元素中的资源引用。它来自文档输入,不能充当文件系统授权判断。
ImageResourceLoader
Docling 共用的图像加载器,负责应用本地和远程加载选项、路径处理及远程 URL 安全检查。
enable_local_fetch
控制受支持后端能否加载本地图像资源的选项。后端绕过共享加载器时,也会绕过这项控制。

框架映射

  • 本指南所述弱点的 CWE 参考: CWE-22

根本原因剖析 (Root Cause)

在受影响的 Docling 版本中,_image_ref_from_odf_image() 会先在 ODF 归档内查找 draw:image 资源。如果查找没有返回数据,后备逻辑就把文档控制的 xlink:href 直接转换为 Path,并在路径存在时调用 read_bytes()。这绕过了共享的 ImageResourceLoader,因此 ODF 处理没有执行 enable_local_fetch、enable_remote_fetch 或通用资源解析规则。图像类型过滤器还接受空扩展名,使无扩展名路径也能通过。文件读取可能发生在图像解码之前;当内容可以解码为图像时,结果文档中的内容泄露也已得到证实。供应商公告记录了任意本地文件读取和 Docling 输出格式中的图像内容泄露;后者限于可解码的图像内容。此 CVE 针对由具有本地文件读取权限的进程转换用户提供的文档;它并不证明每种 Docling 部署都可从网络访问。修复将外部引用传给 ImageResourceLoader.load_image_data() 且不提供本地基础路径,在 ODF 遍历中传递加载器,并从允许的图像扩展名中移除空扩展名。共享加载器默认拒绝本地加载;若启用本地加载,则必须提供受限基础路径。GitHub CNA 给出的评分为 CVSS 4.0 6.9(中等,UI:A);除非另有可访问的服务和转换路径,否则不要称其为无需认证的远程利用。

攻击执行流程分解

步骤 1

文档进入 ODF 转换路径

相关输入是由 Docling 2.107.0 至 2.120.2 处理的 OpenDocument 文件。问题位于 ODF 图像后端,并非所有 Docling 格式或 HTML/RAG 集成都受影响。

步骤 2

图像引用来自文档 XML

ODF 的 draw:image 元素提供 xlink:href。Docling 首先在归档内查找该资源。

步骤 3

归档缺失的部分回退为主机路径

归档内查找失败时,易受影响的 helper 会将同一个引用用作 Path 并直接读取。后备逻辑没有检查共享本地加载选项,也没有将路径限制在归档范围内。

步骤 4

Docling 将字节作为图像资源处理

文件系统读取发生在图像解码之前。如果内容是受支持的图像,字节可能嵌入 DoclingDocument 及其 HTML、Markdown 或 JSON 导出结果。

步骤 5

修复后的加载器恢复资源边界

Docling 2.120.3 将外部 ODF 引用交给 ImageResourceLoader,不提供本地基础路径,并排除无扩展名的引用。转换不可信文档时,应保持本地加载关闭。

源代码对比:漏洞与安全实现

这些是上游代码的局部摘录,并非可独立应用的补丁。修复使用后端的 enable_local_fetch 和 enable_remote_fetch 选项创建 ImageResourceLoader,将其传入 ODF 处理流程,并通过它解析外部引用。base_path=None 时,即使显式启用了本地加载,也会拒绝本地路径,因为加载器无法确定受限目录。补丁还会拒绝空图像扩展名。请升级到 2.120.3 或更高版本,不要只复制此摘录。

源码摘录: docling/backend/opendocument_backend.py — 源码节选

存在漏洞的实现
# 归档中找不到资源时,会回退到文档提供的路径。
if image_data is None and image_url:
    image_path = Path(image_url)
    if image_path.is_file():
        image_data = image_path.read_bytes()
加固后的安全修复
# 修复路径:使用按后端选项配置的共享加载器。
if image_data is None and image_url and image_loader is not None:
    image_data = image_loader.load_image_data(image_url, base_path=None)

工程与系统安全加固清单

参考来源