flawopen.com/Teardowns/cve-2026-105750-docling-html-render-local-file-disclosure
CVE-2026-105750:Docling HTML 渲染导致本地文件泄露
在 2.118.1 之前的 Docling 版本中,如果 Python 代码从 filesystem Path 渲染不可信 HTML,设置 render_page=True 且安装了 Playwright,本地文本文件可能泄露。浏览器路径未执行 enable_local_fetch,也未将访问限制在文档目录内。请升级到 2.118.1 或更高版本。
可以把文档转换器想成一位在浏览器中打开页面并拍照的工作人员。设置本来要求“不要获取本地文件”,但某条渲染路径仍放行了这类请求。如果提交的页面让浏览器显示转换器有权限读取的文件,文件中可见的文字就可能出现在返回文档的图像里。修复会检查该设置,并把允许访问的本地文件限制在源文档目录中。
核心概念与专有名词
Docling HTML backend- Docling 中负责处理 HTML 的组件;它可以选择在无界面浏览器中渲染页面,以捕获视觉布局。
HTMLBackendOptions(render_page=True)- 用于启用浏览器渲染路径的 Python API 选项,默认关闭。
enable_local_fetch- 控制是否可以将本地文件作为文档资源获取的策略选项。每个 backend 都必须对所有资源请求执行此策略。
Playwright- Docling HTML 页面渲染使用的可选浏览器自动化依赖。
Path input- 以文件系统路径提供的源文件。与 stream 输入不同,它会让浏览器渲染流程使用 file URL 来源。
CWE-863- Incorrect Authorization:渲染模式的请求过滤器未执行已配置的本地文件访问策略。
框架映射
- 本指南所述弱点的 CWE 参考: CWE-863
根本原因剖析 (Root Cause)
在受影响的渲染模式版本中,HTMLDocumentBackend._get_browser_request_block_reason() 在检查 enable_local_fetch 或将解析后的路径限制到源文档目录之前,就允许 file: URL。公告指出 Docling 2.82.0–2.90.x 的渲染模式完全没有请求过滤。漏洞边界是浏览器资源请求策略,不是一般 HTML 解析,也不是所有 Docling 部署。GitHub 公告将原因映射为 CWE-863,并将泄露影响列为 CWE-552;本文采用 CWE-863 作为主要根因分类。
攻击执行流程分解
应用启用了可选 HTML 渲染
受影响的部署通过 Python API 使用 HTMLBackendOptions(render_page=True),并安装 Playwright。公告说明默认配置、Docling CLI 和 docling-serve 不在受影响配置范围内。
应用以 filesystem Path 传入 HTML
公告将受影响输入限定为以 Path 传入的不可信 HTML。stream 输入通过 page.set_content() 使用不透明来源,因此不受此 file 子资源路径影响。
无界面浏览器请求本地资源
HTML 可使渲染器请求子资源。受影响的回调允许 file: 请求,却没有执行本地访问授权;即使启用了该选项,也没有像非渲染路径那样把资源限制在源目录。
可读文本可能出现在渲染图像中
公告所述影响限于本地文件在浏览器可视区域显示的文字。从 Docling 2.91.0 起,浏览器禁用了 JavaScript;不要将此问题泛化为任意代码执行或读取不可见字节。
修复后的过滤器恢复两项检查
Docling 2.118.1 允许加载源文档本身;除非启用 enable_local_fetch,否则阻止其他 file 请求;并将允许的本地子资源限制在文档目录内。
源代码对比:漏洞与安全实现
易受影响的代码片段展示了维护者公告所述的 file: 无条件放行规则;它不是完整源文件。修复代码片段依据 upstream commit 1612b88:允许源 HTML 加载,对其他本地文件要求 enable_local_fetch,解析请求路径并将其限制在文档目录中。请升级到 2.118.1 或更高版本,而不是复制这段局部代码。data:、about: 和 blob: 的独立处理不属于本地文件规则。
源码摘录: docling/backend/html_backend.py — 请求与渲染策略的重点代码片段
# 受影响的渲染路径:file: 在检查本地读取策略前已被允许。
if scheme in {"file", "data", "about", "blob"}:
return None
def _is_allowed_browser_file_request(self, request_url: str) -> bool:
local_base_path = self._get_browser_local_base_path()
if local_base_path is not None and request_url == local_base_path.as_uri():
return True # The source document itself must remain loadable.
if not self.options.enable_local_fetch or local_base_path is None:
return False
requested_path = Path(url2pathname(urlparse(request_url).path)).resolve()
return requested_path.is_relative_to(local_base_path.parent)
# 在 _get_browser_request_block_reason() 中:
if scheme == "file":
if self._is_allowed_browser_file_request(request_url):
return None
# 否则返回请求被阻止的原因。
工程与系统安全加固清单
- ✓将
docling和docling-slim升级到 2.118.1 或更高版本;核实运行中的 Python 服务实际使用的包,而不只是开发环境中的版本。 - ✓查找使用
HTMLBackendOptions(render_page=True)的 Python 集成并确认是否安装 Playwright;公告称 CLI、docling-serve、默认渲染模式和 stream 输入不受影响。 - ✓升级前不要用
render_page=True渲染不可信 HTML;如应用兼容,请将文档作为 stream 传入,而不是 filesystemPath。 - ✓使用低权限身份和最小文件系统视图运行转换;不要将应用机密挂载到处理不可信文档的进程中。
- ✓对不可信输入保持
enable_local_fetch关闭,并确认修复后的回调将允许的 file 资源限制在源目录内。 - ✓为源文档、本地获取关闭时的目录外文件,以及本地获取开启时的目录内文件添加回归测试;验证每种情况都按预期阻止或允许。
- ✓将此问题与
CVE-2026-105751区分:后者位于 Docling OpenDocument Format backend,并在 2.120.3 单独修复。请参阅参考资料中的相关文章。 - ✓如果受影响服务处理过不可信 HTML,请评估渲染视口中可能显示的文字,并遵循组织的机密信息暴露响应流程。