CVE-2026-54071 Overview
CVE-2026-54071 is an insecure deserialization vulnerability in BabelDOC, an open-source document translation tool. Versions prior to 0.6.3 deserialize untrusted pickle data when the vendored PDF parser loads CMap files through CMapDB._load_data() in babeldoc/pdfminer/cmapdb.py. A malicious PDF can supply attacker-controlled Encoding or CMapName values, or embed PostScript usecmap operators, to reach the pickle.loads() sink. Path traversal through os.path.join() allows the process to load an attacker-writable .pickle.gz file and execute arbitrary Python code. The issue is tracked as [CWE-502] and is fixed in version 0.6.3.
Critical Impact
A crafted PDF processed by BabelDOC can trigger arbitrary Python code execution with the privileges of the BabelDOC process.
Affected Products
- BabelDOC versions prior to 0.6.3
- Vendored babeldoc/pdfminer/cmapdb.py PDF parser component
- Applications and pipelines that pass untrusted PDFs to BabelDOC
Discovery Timeline
- 2026-08-21 - CVE-2026-54071 published to NVD
- 2026-08-21 - Last updated in NVD database
Technical Details for CVE-2026-54071
Vulnerability Analysis
BabelDOC bundles a fork of pdfminer to parse PDF documents during translation. The CMapDB._load_data() function in babeldoc/pdfminer/cmapdb.py reads gzip-compressed CMap resources from a trusted directory and passes their contents to pickle.loads(). Python's pickle module executes arbitrary code during deserialization when malicious opcodes such as REDUCE reference callables like os.system.
The CMap name used to build the file path originates from PDF-controlled fields, including the font Encoding entry and CMapName value. Embedded PostScript usecmap operators can also reach the same code path. This lets attacker-controlled data traverse into a security-sensitive deserialization sink [CWE-502].
Root Cause
The _normalize_cmap_name() helper strips only a leading forward slash from the supplied CMap name. It does not reject path separators, .. traversal sequences, or absolute paths. When the normalized value is joined to the trusted CMap directory using os.path.join(), an absolute path in the second argument overrides the first, and traversal sequences escape the intended directory. The resulting path resolves to any .pickle.gz file the attacker can write on the local file system.
Attack Vector
Exploitation requires local access and user interaction: an attacker must both place a malicious .pickle.gz payload at a predictable filesystem location and induce a user or automated pipeline to translate a crafted PDF with BabelDOC. The PDF references the attacker-controlled path through its Encoding, CMapName, or usecmap fields. When BabelDOC parses the document, pickle.loads() executes the payload with the privileges of the BabelDOC process.
# Security patch in babeldoc/const.py - Release v0.6.3
import threading
from pathlib import Path
-__version__ = "0.6.2"
+__version__ = "0.6.3"
CACHE_FOLDER = Path.home() / ".cache" / "babeldoc"
Source: BabelDOC Commit 28f784c. The version bump accompanies the parser hardening in cmapdb.py shipped in the v0.6.3 release.
Detection Methods for CVE-2026-54071
Indicators of Compromise
- Presence of .pickle.gz files outside the BabelDOC-vendored CMap directory that are read during PDF translation.
- PDF documents whose font Encoding or CMapName values contain absolute paths, .. traversal sequences, or unexpected path separators.
- Unexpected child processes spawned by the Python interpreter running BabelDOC, especially shell or network utilities.
Detection Strategies
- Inventory BabelDOC installations and flag any version below 0.6.3 reported by pip show babeldoc or the babeldoc/const.py__version__ string.
- Instrument the CMapDB._load_data() code path to log the resolved file path and reject values that leave the vendored CMap directory.
- Statically scan incoming PDFs for suspicious Encoding, CMapName, and PostScript usecmap values before translation.
Monitoring Recommendations
- Monitor process trees for BabelDOC workers spawning interactive shells, curl, wget, or interpreter subprocesses.
- Alert on file writes to .pickle.gz paths on hosts that run BabelDOC translation jobs.
- Forward BabelDOC application logs and host telemetry to a central data lake for correlation with PDF ingestion events.
How to Mitigate CVE-2026-54071
Immediate Actions Required
- Upgrade BabelDOC to version 0.6.3 or later on every host and container image that processes PDFs.
- Quarantine untrusted PDFs and refuse to translate documents from unverified sources until the upgrade is complete.
- Audit filesystem locations writable by the BabelDOC service account and remove any unexpected .pickle.gz files.
Patch Information
The maintainers fixed the issue in BabelDOC 0.6.3. See the GitHub Security Advisory GHSA-m8gf-v64p-gfmg, the BabelDOC Release Notes v0.6.3, the BabelDOC Release Tag v0.6.3, and the BabelDOC Commit 28f784c for the corresponding fix.
Workarounds
- Run BabelDOC under a dedicated low-privilege user with no write access to directories that the parser searches for CMap resources.
- Execute translation jobs inside a sandbox or ephemeral container with a read-only filesystem to prevent attacker-controlled .pickle.gz files from persisting.
- Restrict PDF intake to trusted sources and pre-validate Encoding, CMapName, and usecmap fields until the patched release is deployed.
# Upgrade BabelDOC to the patched release
pip install --upgrade "babeldoc>=0.6.3"
# Verify the installed version
python -c "import babeldoc; print(babeldoc.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

