GHSA-f83h-ghpp-7wcc: Insecure Deserialization (pickle) in pdfminer.six CMap Loader — Local Privesc
🚀 OverviewThis report **demonstrates a real-world privilege escalation** vulnerability in [pdfminer.six](https://github.com/pdfminer/pdfminer.six) due to unsafe usage of Python's `pickle` module for CMap file loading.
It shows how a low-privileged user can gain root access (or escalate to any service account) by exploiting insecure deserialization in a typical multi-user or server environment.![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)🚨 Special NoteThis advisory addresses a distinct vulnerability from [GHSA-wf5f-4jwr-ppcp (CVE-2025-64512)](https://github.com/pdfminer/pdfminer.six/security/advisories/GHSA-wf5f-4jwr-ppcp).While the previous CVE claims to mitigate issues related to unsafe deserialization, the patch introduced in commit [b808ee05dd7f0c8ea8ec34bdf394d40e63501086](https://github.com/pdfminer/pdfminer.six/commit/b808ee05dd7f0c8ea8ec34bdf394d40e63501086) does not address the vulnerability reported here.Based on testing performed against the latest version of the library ([comparison view](https://github.com/pdfminer/pdfminer.six/compare/20250506...20251107)), the issue remains exploitable through local privilege escalation due to continued unsafe use of pickle files. The **Dockerfile** is hence modified to run test against this claim.This demonstrates that the patch for **CVE-2025-64512** is incomplete: the vulnerability remains exploitable. This advisory therefore documents a distinct, independently fixable flaw. A correct remediation must remove the dependency on pickle files (or otherwise eliminate unsafe deserialization) and replace it with a safe, auditable data-handling approach so the library can operate normally without relying on ```pickle```📚 Table of Contents[🔍 Background](#-background)[🐍 Vulnerability Description](#-vulnerability-description)[🎭 Demo Scenario](#-demo-scenario)[🧨 Technical Details](#-technical-details)[🔧 Setup and Usage](#-setup-and-usage)[📝 Step-by-step Walkthrough](#-step-by-step-walkthrough)[🛡️ Security Standards & References](#-security-standards--references)🔍 Background**pdfminer.six** is a popular Python library for extracting text and information from PDF files. It supports CJK (Chinese, Japanese, Korean) fonts via external CMap files, which it loads from disk using Python's `pickle` module.🐍 **Security Issue:**
If the CMap search path (`CMAP_PATH` or default directories) includes a world-writable or user-writable directory, an attacker can place a malicious `.pickle.gz` file that will be loaded and deserialized by pdfminer.six, leading to arbitrary code execution.🐍 Vulnerability Description**Component:** pdfminer.six CMap loading (`pdfminer/cmapdb.py`)**Issue:** Loads and deserializes `.pickle.gz` files using Python’s `pickle` module, which is unsafe for untrusted data.**Exploitability:** If a low-privileged user can write to any directory in `CMAP_PATH`, they can execute code as the user running pdfminer—potentially root or a privileged service.**Impact:** Full code execution as the service user, privilege escalation from user to root, persistence, and potential lateral movement.![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)🎭 Demo Scenario**Environment:**🐧 Alpine Linux (Docker container)👨‍💻 Two users:`user1` (attacker: low-privilege)`root` (victim: runs privileged PDF-processing script)🗂️ Shared writable directory: `/tmp/uploads`🛣️ `CMAP_PATH` set to `/tmp/uploads` for the privileged script📦 pdfminer.six installed system-wide**Attack Flow:**🕵️‍♂️ `user1` creates a malicious CMap file (`Evil.pickle.gz`) in `/tmp/uploads`.👑 The privileged service (`root`) processes a PDF or calls `get_cmap("Evil")`.💣 The malicious pickle is deserialized, running arbitrary code as root.🎯 The exploit creates a flag file in `/root/pwnedByPdfminer` as proof.![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)🧨 Technical Details**Vulnerability Type:** Insecure deserialization of untrusted data using Python's `pickle`**Attack Prerequisites:** Attacker can write to a directory included in `CMAP_PATH`**Vulnerable Line:***In `pdfminer/cmapdb.py`'s `_load_data` method*https://github.com/pdfminer/pdfminer.six/blob/20250506/pdfminer/cmapdb.py#L246**Proof of Concept:** See `createEvilPickle.py`, `evilmod.py`, and `processPdf.py`**Exploit Chain:**Attacker places a malicious `.pickle.gz` file in the CMap search path.Privileged process (e.g., root) loads a CMap, triggering pickle deserialization.Arbitrary code executes with the privilege of the process (root/service account).![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)🔧 Setup and Usage📁 Files</> Dockerfile</> evilmod.py</> createEvilPickle.py</> processPDF.py![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)1️⃣ Build and start the demo container2️⃣ In the container, open two shells in parallel (or switch users in one):🕵️‍♂️ Shell 1 (Attacker: user1)👑 Shell 2 (Victim: root)3️⃣ Proof of escalation![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)📝 Step-by-step Walkthrough**user1** uses `createEvilPickle.py` to craft and place a malicious CMap pickle in a shared upload directory.The **root** user runs a typical PDF-processing script, which loads CMap files from that directory.The exploit triggers, running arbitrary code as root.The attacker now has proof of code execution as root (and, in a real attack, could escalate further).![line](https://user-images.githubusercontent.com/74038190/212284100-561aa473-3905-4a80-b561-0d28506553ee.gif)🛡️ Security Standards & References**CVSS (Common Vulnerability Scoring System):****Base Score:** 7.8 (High)**Vector:** `AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`**OWASP Top 10:**[A08:2021 - Software and Data Integrity Failures](https://owasp.org/Top10/A08_2021-Software_and_Data_Integrity_Failures/)[A03:2021 - Injection](https://owasp.org/Top10/A03_2021-Injection/) (by analogy, as it's code injection via deserialization)**MITRE CWE References:**[CWE-502: Deserialization of Untrusted Data](https://cwe.mitre.org/data/definitions/502.html)[CWE-915: Improperly Controlled Modification of Dynamically-Determined Object Attributes](https://cwe.mitre.org/data/definitions/915.html)**MITRE ATT&CK Techniques:**[T1055: Process Injection](https://attack.mitre.org/techniques/T1055/)[T1548: Abuse Elevation Control Mechanism](https://attack.mitre.org/techniques/T1548/)
CVSS v3.1: 7.8