flawopen.com/Teardowns/cve-2026-105750-docling-html-render-local-file-disclosure
CVE-2026-105750: Docling HTML Render Local File Disclosure
Docling versions before 2.118.1 can disclose local text files when Python code renders untrusted HTML from a filesystem Path with render_page=True and Playwright installed. The HTML browser path failed to enforce enable_local_fetch and directory confinement. Upgrade to 2.118.1 or later.
A document converter is like a clerk who photographs a page in a browser. A setting said “do not fetch local files,” but one browser-rendering path waved local-file requests through anyway. If the submitted page could make that browser display a file the converter could read, the file’s visible text could end up in the returned document image. The fix checks the setting and keeps allowed local files inside the source document’s directory.
Core Concepts & Subsystem Terms
Docling HTML backend- The Docling component that parses HTML and can optionally render the page in a headless browser to capture its visual layout.
HTMLBackendOptions(render_page=True)- A Python-only option that enables the headless-browser rendering path. It is off by default.
enable_local_fetch- A policy option that controls whether local files may be fetched as document resources. A backend must enforce it for every resource request.
Playwright- The optional browser automation dependency used by Docling’s HTML page-rendering mode.
Path input- A filesystem path used as the source document. Unlike stream input, it gives the browser-rendering flow a file URL origin.
CWE-863- Incorrect Authorization: the render-mode request filter failed to enforce the configured local-file access policy.
Framework mappings
- CWE reference for the weakness described in this guide: CWE-863
Root Cause Analysis
In affected render-mode versions, HTMLDocumentBackend._get_browser_request_block_reason() treated file: URLs as allowed before it checked enable_local_fetch or confined the resolved path to the source document’s directory. For Docling 2.82.0–2.90.x, the advisory says render mode did not filter requests at all. The vulnerable boundary is the browser resource-request policy, not general HTML parsing or every Docling deployment. The GitHub advisory classifies CWE-863 and also lists CWE-552 for the disclosure impact; this page uses CWE-863 as the primary root-cause mapping.
Step-by-Step Attack Flow
An application enables optional HTML rendering
The vulnerable deployment uses the Python API with HTMLBackendOptions(render_page=True) and has Playwright installed. The default configuration, Docling CLI, and docling-serve are outside the advisory’s affected configuration.
The application submits HTML as a filesystem Path
The advisory limits the affected input to untrusted HTML passed as a Path. Stream inputs use page.set_content() with an opaque origin and are not affected by this file-subresource path.
The headless browser requests a local resource
HTML can cause browser-rendered subresources to be requested. The affected request callback allowed file: requests without enforcing the configured local-fetch permission; even with local fetch enabled, it lacked the source-directory confinement used by the non-render path.
Readable text can appear in the rendered image
The disclosed impact is limited to text a local file exposes visibly inside the browser viewport. JavaScript is disabled in the browser from Docling 2.91.0; do not generalize this issue to arbitrary code execution or invisible bytes.
The fixed filter restores both policy checks
Docling 2.118.1 allows the source document itself, blocks other file requests unless enable_local_fetch is true, and confines allowed file subresources to the source document’s directory.
Source Code: Flaw vs. Secure Implementation
The vulnerable excerpt shows the unconditional file: allow rule documented by the maintainer advisory; it is not a complete source file. The fixed excerpt follows upstream commit 1612b88: allow the source HTML file to load, require enable_local_fetch for other local files, resolve the requested path, and enforce source-directory containment. Upgrade to 2.118.1 or later rather than copying this focused excerpt. The separate data:, about:, and blob: handling remains outside the local-file rule.
Source excerpt: docling/backend/html_backend.py — focused excerpts from the affected and fixed request policy
# Affected render path: file: was allow-listed before local-fetch policy checks.
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)
# In _get_browser_request_block_reason():
if scheme == "file":
if self._is_allowed_browser_file_request(request_url):
return None
# Otherwise return a reason that the request is blocked.
Engineering & System Hardening Checklist
- ✓Upgrade both
doclinganddocling-sliminstallations to 2.118.1 or later; verify the package used by the running Python service, not only the developer environment. - ✓Find Python integrations that set
HTMLBackendOptions(render_page=True)and confirm whether Playwright is installed; the CLI, docling-serve, default render mode, and stream inputs are not affected according to the advisory. - ✓Until upgraded, do not render untrusted HTML with
render_page=True; where compatible, pass the document as a stream instead of a filesystemPath. - ✓Run document conversion with a low-privilege identity and a minimal filesystem view; do not mount application secrets into a process that parses untrusted documents.
- ✓Keep
enable_local_fetchdisabled for untrusted input and verify the patched request callback confines allowed file resources to the source directory. - ✓Add regression tests for the source document, an unrelated local file with local fetch disabled, and an in-directory file with local fetch enabled; assert the request filter blocks or permits each expected case.
- ✓Keep this issue distinct from
CVE-2026-105751: that disclosure is in Docling’s OpenDocument Format backend and has a separate fix in 2.120.3. See the related article in the references. - ✓If affected services processed untrusted HTML, assess what text was visible in rendered page viewports and follow the organization’s secret-exposure response process.