FlawOpen

flawopen.com/Teardowns/cve-2026-105750-docling-html-render-local-file-disclosure

● CVE-2026-105750 · CVSS 5.9 · Moyenne
Recherche · FlawOpen

CVE-2026-105750 : divulgation de fichiers locaux lors du rendu HTML de Docling

Les versions de Docling antérieures à 2.118.1 peuvent divulguer des fichiers texte locaux lorsque du code Python rend du HTML non fiable depuis un filesystem Path avec render_page=True et Playwright installé. Le chemin du navigateur n’appliquait pas enable_local_fetch et ne limitait pas l’accès au répertoire du document. Passez à 2.118.1 ou ultérieur.

💡 Explication en Langage Simple (ELI5)

Imaginez un convertisseur comme un employé qui photographie une page ouverte dans un navigateur. Un réglage disait « ne récupère pas de fichiers locaux », mais un chemin de rendu laissait passer ces requêtes. Si la page fournie amenait le navigateur à afficher un fichier que le convertisseur pouvait lire, son texte visible pouvait se retrouver dans l’image du document renvoyé. Le correctif vérifie le réglage et limite les fichiers locaux autorisés au répertoire du document source.

Concepts Clés et Termes

Docling HTML backend
Composant Docling qui analyse le HTML et peut afficher la page dans un navigateur sans interface afin d’en capturer la présentation visuelle.
HTMLBackendOptions(render_page=True)
Option de l’API Python qui active le rendu dans un navigateur. Elle est désactivée par défaut.
enable_local_fetch
Option de politique qui détermine si des fichiers locaux peuvent être récupérés comme ressources du document. Chaque backend doit l’appliquer à chaque requête de ressource.
Playwright
Dépendance facultative d’automatisation de navigateur utilisée pour le rendu des pages HTML de Docling.
Path input
Fichier source fourni sous forme de chemin du système de fichiers. Contrairement à un flux, il donne au navigateur une origine file URL.
CWE-863
Incorrect Authorization : le filtre de requêtes du mode rendu n’appliquait pas la politique configurée pour l’accès aux fichiers locaux.

Correspondances de référentiels

  • Référence CWE pour la faiblesse décrite dans ce guide : CWE-863

Analyse de Cause Racine

Dans les versions concernées en mode rendu, HTMLDocumentBackend._get_browser_request_block_reason() autorisait les URL file: avant de vérifier enable_local_fetch ou de limiter le chemin résolu au répertoire du document source. Pour Docling 2.82.0–2.90.x, l’avis précise que le mode rendu ne filtrait aucune requête. La frontière vulnérable est la politique de requêtes de ressources du navigateur, et non l’analyse HTML en général ni tous les déploiements Docling. L’avis GitHub classe la cause en CWE-863 et mentionne aussi CWE-552 pour l’impact de divulgation ; cette page retient CWE-863 comme classification principale de la cause.

Déroulement de l'Attaque Étape par Étape

Étape 1

L’application active le rendu HTML facultatif

Le déploiement vulnérable utilise l’API Python avec HTMLBackendOptions(render_page=True) et Playwright installé. La configuration par défaut, la CLI Docling et docling-serve ne font pas partie de la configuration concernée par l’avis.

Étape 2

L’application fournit le HTML sous forme de filesystem Path

L’avis limite l’entrée concernée au HTML non fiable fourni comme Path. Les entrées en flux utilisent page.set_content() avec une origine opaque et ne sont pas concernées par ce chemin de sous-ressource file.

Étape 3

Le navigateur sans interface demande une ressource locale

Le HTML peut déclencher des demandes de sous-ressources pendant le rendu. Le rappel concerné autorisait file: sans appliquer l’autorisation d’accès local ; même lorsque l’option était activée, il ne confinait pas la ressource au répertoire source, contrairement au chemin sans rendu.

Étape 4

Du texte lisible peut apparaître dans l’image rendue

L’impact décrit se limite au texte qu’un fichier local affiche dans la zone visible du navigateur. JavaScript est désactivé dans le navigateur depuis Docling 2.91.0 ; ne généralisez pas cette faille en exécution de code arbitraire ou lecture d’octets invisibles.

Étape 5

Le filtre corrigé rétablit les deux contrôles

Docling 2.118.1 autorise le chargement du document source lui-même, bloque les autres requêtes file sauf si enable_local_fetch est activé et confine les sous-ressources locales autorisées au répertoire du document.

Code Source : Vulnérable vs Sécurisé

L’extrait vulnérable montre la règle qui autorisait file: sans condition, comme le décrit l’avis des mainteneurs ; ce n’est pas un fichier source complet. L’extrait corrigé suit le commit upstream 1612b88 : il autorise le HTML source, exige enable_local_fetch pour les autres fichiers locaux, résout le chemin demandé et impose son confinement au répertoire du document. Passez à 2.118.1 ou ultérieur au lieu de copier cet extrait ciblé. Le traitement distinct de data:, about: et blob: ne relève pas de la règle des fichiers locaux.

Extrait source: docling/backend/html_backend.py — extraits ciblés de la politique de requêtes et de rendu

IMPLÉMENTATION VULNÉRABLE
# Chemin de rendu concerné : file: était autorisé avant les contrôles de la politique d’accès local.
if scheme in {"file", "data", "about", "blob"}:
    return None
PATCH SÉCURISÉ ET ROBUSTE
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)

# Dans _get_browser_request_block_reason() :
if scheme == "file":
    if self._is_allowed_browser_file_request(request_url):
        return None
    # Sinon, renvoyer la raison du blocage de la requête.

Liste de Contrôle de Sécurité pour l'Ingénierie

Sources