FlawOpen

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

● CVE-2026-105751 · CVSS v4 6.9 · Medium
FlawOpen Security Research

CVE-2026-105751: Docling ODF File Disclosure

Docling’s ODF backend could treat a document’s image reference as a local path and read it outside the archive. Upgrade to 2.120.3; the fix sends resource loading through the shared fetch-control component.

CVSS vectorCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:N/VA:N/SC:L/SI:N/SA:N
💡 Plain English Explainer (ELI5)

A librarian checks whether a picture is inside the scrapbook. If it is missing, the flawed reader walks to a filing cabinet and opens whatever path the scrapbook label names, without checking the library’s ‘no local fetching’ rule. The fix makes the reader use the same guarded resource desk as the other document formats.

Core Concepts & Subsystem Terms

OpenDocument Format (ODF)
An office-document format family that includes .odt text documents. Docling reads image references from the document’s XML content.
draw:image
An ODF XML element that describes an image in the document. Its xlink:href value identifies the image resource.
xlink:href
The resource reference carried by an ODF image element. It is document input and must not be trusted as a filesystem authorization decision.
ImageResourceLoader
Docling’s shared image loader. It applies local and remote fetch options, path handling, and remote-URL safety checks.
enable_local_fetch
An opt-in that controls whether supported backends may fetch local image resources. A backend that bypasses the shared loader also bypasses this control.

Framework mappings

  • CWE reference for the weakness described in this guide: CWE-22

Root Cause Analysis

In affected Docling releases, _image_ref_from_odf_image() first tried to find the draw:image resource inside the ODF archive. If that lookup returned no bytes, the fallback converted the document-controlled xlink:href directly to Path and called read_bytes() whenever the path existed. This bypassed the shared ImageResourceLoader, so ODF processing did not enforce enable_local_fetch, enable_remote_fetch, or the common resource-resolution rules. The image-type filter also accepted an empty suffix, which admitted extensionless paths. The file read can occur before image decoding; disclosure in the resulting document is demonstrated when the bytes can be decoded as an image. The vendor advisory records arbitrary local file reading and image-content disclosure through Docling’s output formats, while bounding the latter to decodable image content. This CVE is about a supplied document being converted by a process with local file access; it does not establish that every Docling deployment is remotely reachable. Docling’s fix passes external references through ImageResourceLoader.load_image_data() with no local base path, propagates the loader through ODF traversal, and removes the empty suffix from the accepted image extensions. The shared loader denies local fetching by default and requires a confined base path if local fetching is enabled. The GitHub CNA rates the issue CVSS 4.0 6.9 Moderate (UI:A); do not present it as unauthenticated remote exploitation without an additional reachable service and conversion path.

Step-by-Step Attack Flow

Step 1

A document enters an ODF conversion path

The relevant input is an OpenDocument file processed by Docling 2.107.0 through 2.120.2. The issue is in the ODF image backend, not every Docling format or every HTML/RAG integration.

Step 2

The image reference comes from document XML

The ODF draw:image element supplies an xlink:href. Docling first looks for that resource inside the archive.

Step 3

A missing archive part falls through to a host path

When the in-archive lookup fails, the vulnerable helper used the same reference as a Path and read it directly. The fallback did not consult the shared local-fetch setting or confine the path to the archive.

Step 4

Docling processes the bytes as an image resource

The filesystem read occurs before image decoding. When the file’s contents are a supported image, those bytes can be embedded in the resulting DoclingDocument and its HTML, Markdown, or JSON export.

Step 5

The patched loader restores the resource boundary

Docling 2.120.3 routes external ODF references through ImageResourceLoader, passes no local base path, and excludes extensionless references from the accepted image suffixes. Keep local fetching disabled when converting untrusted documents.

Source Code: Flaw vs. Secure Implementation

These are focused upstream excerpts, not a standalone patch. The fix constructs ImageResourceLoader with the backend’s enable_local_fetch and enable_remote_fetch options, passes it into ODF image processing, and routes external references through the loader. With base_path=None, local path loading is rejected even if local fetching is explicitly enabled because the loader cannot establish a confined directory. The patch also rejects empty image suffixes. Upgrade to 2.120.3 or later rather than copying only this excerpt.

Source excerpt: docling/backend/opendocument_backend.py — focused source excerpt

UNPATCHED FLAW
# A missing in-archive resource fell back to the document-controlled path.
if image_data is None and image_url:
    image_path = Path(image_url)
    if image_path.is_file():
        image_data = image_path.read_bytes()
HARDENED SECURE PATCH
# Fixed path: use the shared loader configured with backend fetch options.
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)

Engineering & System Hardening Checklist

Sources