Details
### Summary
When the HTML backend renders pages in a headless browser (`HTMLBackendOptions(render_page=True)`), the `enable_local_fetch` option is not enforced. A crafted HTML file can embed an arbitrary local file (for example with `<iframe src="file:///...">`), and that file's contents appear in the page image attached to the returned `DoclingDocument`.
### Details
In render mode, Playwright requests are filtered by `HTMLDocumentBackend._get_browser_request_block_reason`. In affected versions, this check allowed `file:` URLs unconditionally, before reading any option. As a result:
- `enable_local_fetch=False` did not block local file access, and
- even with `enable_local_fetch=True`, file access was not limited to the source document's directory, unlike the non-render path (`ImageResourceLoader`), which rejects absolute paths and path traversal.
Versions 2.82.0–2.90.x did no request filtering in render mode at all.
The browser runs with JavaScript disabled (from 2.91.0), so disclosure is passive: only what Chromium renders visibly inside the page viewport ends up in the page image.
Only `Path` inputs are affected. They are loaded through a `file://` URL. Stream inputs are loaded with `page.set_content()` into an opaque origin, from which Chromium does not load `file://` subresources.
### Impact
An attacker who can submit HTML for conversion can read any text file the conversion process can read (for example `.env` files, credential files, or other users' documents on a shared host) by having it rendered into the page image.
Only applications that meet **all** of these conditions are affected:
- they set `HTMLBackendOptions(render_page=True)` in Python,
- they have the optional `playwright` dependency installed, and
- they pass untrusted HTML as a filesystem `Path`.
The following are **not** affected: the default configuration (`render_page=False`), the `docling` CLI, `docling-serve`, and the EPUB, Markdown, XBRL and email backends.
### Patches
Fixed in **2.118.1** (#3948). In render mode, `file:` requests are now blocked unless `enable_local_fetch=True`, and allowed requests are limited to the source document's directory.
### Workarounds
If you can't upgrade, don't use `render_page=True` on untrusted HTML, or pass the input as a stream instead of a `Path`.
### Credits
Reported by @priyankn.