CVE-2026-105745: Arbitrary Code Execution via Malicious Entrypoint Discovery in Docling base_factory
Vulnerability ID: CVE-2026-105745
CVSS Score: 6.7
Published: 2026-10-07
Docling prior to version 2.131.0 is vulnerable to arbitrary local code execution during module initialization due to incorrect order of operations in its plugin discovery system. Even when the default option to reject external plugins is active, Docling utilizes Pluggy to scan and import entrypoints before performing namespace validation.
TL;DR
Docling unconditionally imported external third-party entrypoint modules during initialization before checking namespace validation parameters, allowing malicious local packages to execute code at import time.
Technical Details
- CWE ID: CWE-696
- Attack Vector: Local
- CVSS: 6.7 (Medium)
- EPSS Score: 0.00109
- Impact: Arbitrary Code Execution
- Exploit Status: none
- KEV Status: No
Affected Systems
- Docling Library (Python Package)
- Docling Slim (Python Package)
-
docling: >= 2.27.0, < 2.131.0 (Fixed in:
2.131.0) -
docling-slim: >= 2.27.0, < 2.131.0 (Fixed in:
2.131.0)
Code Analysis
Commit: 0f443b3
Fix load_from_plugins validation checking logic order using importlib.metadata entry_points parsing directly
--- a/docling/models/factories/base_factory.py
+++ b/docling/models/factories/base_factory.py
@@ -4,6 +4,7 @@
import enum
import logging
from abc import ABCMeta
+from importlib.metadata import entry_points
from typing import Generic, Optional, Type, TypeVar
from pluggy import PluginManager
@@ -96,19 +97,27 @@ def load_from_plugins(
plugin_name = plugin_name or self.plugin_name
plugin_manager = PluginManager(plugin_name)
- plugin_manager.load_setuptools_entrypoints(plugin_name)
- for plugin_name, plugin_module in plugin_manager.list_name_plugin():
- plugin_module_name = str(plugin_module.__name__) # type: ignore
+ # Decide from the entry point metadata whether a plugin is allowed
+ # before importing it, so that disallowed plugin modules are never
+ # imported.
+ for entry_point in entry_points(group=plugin_name):
+ if plugin_manager.get_plugin(entry_point.name) is not None:
+ continue
- if not allow_external_plugins and not plugin_module_name.startswith(
+ if not allow_external_plugins and not entry_point.module.startswith(
"docling."
):
logger.warning(
- f"The plugin {plugin_name} will not be loaded because Docling is being executed with allow_external_plugins=false."
+ f"The plugin {entry_point.name} will not be loaded because Docling is being executed with allow_external_plugins=false."
)
continue
+ plugin_manager.register(entry_point.load(), name=entry_point.name)
+
+ for plugin_name, plugin_module in plugin_manager.list_name_plugin():
+ plugin_module_name = str(plugin_module.__name__) # type: ignore
+
Mitigation Strategies
- Upgrade docling to 2.131.0 or newer
- Restrict site-packages folder write privileges
- Implement requirements integrity checks with hashes
- Verify that docling-core is upgraded to 2.98.0 or newer
Remediation Steps:
- Identify all current python environments utilizing docling.
- Run 'pip install --upgrade docling>=2.131.0' to implement the patch.
- Execute the provided inspection python script to audit registered entrypoints for compliance.
- Ensure virtual environments are locked and unprivileged users cannot write dependency extensions.
References
- GHSA-9jxx-vjrv-h2rq Security Advisory
- Fix Loading Order of External Plugins Pull Request
- Security Correction Commit
- Docling v2.131.0 Release Changelog
- NVD Vulnerability Detail Details
Read the full report for CVE-2026-105745 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)