CVE-2026-112391 Overview
CVE-2026-112391 is a denial-of-service vulnerability in Pillow, the widely used Python imaging library. The flaw resides in the PdfParser.get_value() function, which recursively parses nested PDF objects without enforcing a depth limit. When an application opens an existing PDF for append and saves an image, the parser follows attacker-controlled arrays and dictionaries. A deeply nested PDF triggers an uncaught RecursionError or terminates the worker process. The vulnerability affects Pillow versions 5.1.0 through 13.0.0 and is categorized under CWE-835: Loop with Unreachable Exit Condition. Version 13.0.0 introduces a default max_nesting limit of 900 to resolve the issue.
Critical Impact
An attacker can crash Pillow-backed services by supplying a malicious PDF to any workflow that performs PDF append operations, causing denial of service of image-processing workers.
Affected Products
- Pillow Python imaging library versions 5.1.0 through 13.0.0 (excluded)
- Applications performing PDF append operations with PIL.PdfParser
- Downstream services ingesting user-supplied PDFs through Pillow
Discovery Timeline
- 2026-10-19 - CVE-2026-112391 published to NVD
- 2026-10-20 - Last updated in NVD database
Technical Details for CVE-2026-112391
Vulnerability Analysis
The defect lives in src/PIL/PdfParser.py within the get_value() method. The parser is designed to walk PDF objects, including arrays and dictionaries that may themselves reference further objects. Prior to the fix, the max_nesting parameter defaulted to -1, meaning recursion continued until Python's interpreter stack was exhausted.
When Pillow opens an existing PDF with append mode enabled to add a new image, the parser reads the existing object graph. An attacker who controls that PDF can craft arbitrarily deep nesting of arrays or dictionaries. The resulting unbounded recursion raises an uncaught RecursionError, which propagates up and terminates the calling worker.
Root Cause
The root cause is missing recursion depth enforcement in the recursive descent parser. The sentinel value -1 disabled the depth check entirely, so the function get_value() relied solely on CPython's recursion limit. Attacker-controlled structural depth therefore translated directly into process termination, satisfying the conditions of CWE-835.
Attack Vector
Exploitation requires an application that calls Pillow to save an image into an existing PDF with append enabled, where the existing PDF originates from an untrusted source. The attacker uploads or supplies a crafted PDF containing deeply nested objects. When the Pillow worker opens the file for append, PdfParser.get_value() recurses until the interpreter aborts the thread. No authentication or user interaction is required when the ingestion endpoint is network-reachable.
data: bytes | bytearray | memoryview | mmap.mmap,
offset: int,
expect_indirect: IndirectReference | None = None,
- max_nesting: int = -1,
+ max_nesting: int = 900,
) -> tuple[Any, int | None]:
if max_nesting == 0:
return None, None
Source: Pillow commit 94cb11c. The patch replaces the unlimited default with a bounded depth of 900, forcing get_value() to return None once the limit is reached and preventing stack exhaustion.
Detection Methods for CVE-2026-112391
Indicators of Compromise
- Repeated worker crashes or process restarts in services that ingest PDF files through Pillow
- Python tracebacks containing RecursionError originating from PIL/PdfParser.py and get_value
- Uploaded PDF objects with abnormally deep nested arrays or dictionaries relative to typical business documents
Detection Strategies
- Inventory Python dependencies and flag any installation of Pillow at versions >=5.1.0,<13.0.0
- Enable application-level exception logging to capture RecursionError events linked to PDF processing endpoints
- Add file-shape heuristics on PDF uploads that reject documents exceeding a reasonable object-nesting depth
Monitoring Recommendations
- Alert on sudden spikes in image-processing worker restarts or OOM/stack-overflow signals
- Track volume and size distribution of PDFs submitted to Pillow-backed APIs for anomaly detection
- Correlate web application firewall (WAF) telemetry on PDF uploads with downstream service health metrics
How to Mitigate CVE-2026-112391
Immediate Actions Required
- Upgrade Pillow to version 13.0.0 or later across all production and build environments
- Audit application code paths that call Image.save() with PDF append mode on untrusted files
- Isolate PDF-processing workers so a crash does not cascade to shared services
Patch Information
The fix is included in Pillow 13.0.0. See the Pillow 13.0.0 release notes and GHSA-254f-3936-288h. The patch commit 94cb11c sets the default max_nesting to 900 in PdfParser.get_value().
Workarounds
- Avoid opening untrusted PDFs with append mode until the upgrade is deployed
- Pre-validate incoming PDFs with a hardened parser that rejects documents exceeding a bounded object-nesting depth
- Wrap Pillow PDF operations in a subprocess with a strict sys.setrecursionlimit() and timeout to contain crashes
# Pin a fixed Pillow version in requirements
pip install --upgrade 'Pillow>=13.0.0'
# Verify the installed version
python -c "import PIL; print(PIL.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

