Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-59936

CVE-2026-59936: pypdf Library DOS Vulnerability

CVE-2026-59936 is a denial of service vulnerability in pypdf that allows attackers to trigger infinite loops via crafted PDFs with unterminated inline images. This article covers technical details, affected versions, and fixes.

Published:

CVE-2026-59936 Overview

CVE-2026-59936 is a denial of service vulnerability in pypdf, a widely used pure-Python PDF library. Versions prior to 6.14.1 fail to detect end-of-stream conditions when parsing inline images within a PDF page content stream. An attacker can craft a PDF containing an unterminated inline image, causing pypdf to enter an infinite loop while searching for the inline image end marker. The condition triggers during common operations such as page text extraction. The issue is classified as uncontrolled resource consumption [CWE-400] and is fixed in pypdf version 6.14.1.

Critical Impact

Any application that ingests untrusted PDFs and calls text extraction or content stream parsing routines can be forced into an infinite loop, exhausting CPU and blocking worker processes.

Affected Products

  • pypdf versions prior to 6.14.1
  • Python applications that call extract_text() or otherwise parse page content streams from untrusted PDFs
  • Downstream libraries and services that embed pypdf for PDF ingestion or indexing

Discovery Timeline

  • 2026-07-08 - CVE-2026-59936 published to NVD
  • 2026-07-09 - Last updated in NVD database

Technical Details for CVE-2026-59936

Vulnerability Analysis

The vulnerability resides in pypdf's inline image parsing logic within pypdf/generic/_data_structures.py. PDF page content streams can embed inline images delimited by the BI (begin image), ID (image data), and EI (end image) operators. When pypdf encounters an inline image, it iterates through the stream searching for the EI end marker.

The parser calls read_non_whitespace(stream) inside a while True loop but does not verify whether the read returned an empty token indicating end-of-stream. When a crafted PDF omits the EI marker, the stream pointer reaches EOF and read_non_whitespace returns an empty byte string. The loop then repeatedly seeks back one byte and re-reads the same empty result, never advancing and never terminating.

The effect is a single-threaded CPU spin. Applications processing attacker-supplied PDFs, such as document ingestion pipelines, mail scanners, or search indexers, will pin a worker at 100% CPU until externally terminated.

Root Cause

The root cause is missing end-of-stream detection during token scanning inside the inline image end marker search loop. The parser trusted that the input stream would eventually yield an EI operator and did not validate loop progress.

Attack Vector

Exploitation requires only that a target application parse a malicious PDF. No authentication, user interaction beyond file submission, or network position is required. Any endpoint that accepts PDF uploads or fetches PDFs from untrusted sources is reachable.

python
# Patch from pypdf/generic/_data_structures.py
# Source: https://github.com/py-pdf/pypdf/commit/ec3b14596186c40caca7cf8ab9b2155203e01b5b

         settings = DictionaryObject()
         while True:
             tok = read_non_whitespace(stream)
+            if not tok:
+                raise PdfStreamError("Unexpected end of stream.")
             stream.seek(-1, 1)
             if tok == b"I":
                 # "ID" - begin of image data

The fix raises PdfStreamError when read_non_whitespace returns an empty token, breaking the infinite loop and surfacing a parse error to the caller.

Detection Methods for CVE-2026-59936

Indicators of Compromise

  • Python processes running pypdf sustaining 100% CPU utilization on a single core with no forward progress
  • PDF files containing BI and ID operators without a corresponding EI end marker in the page content stream
  • Worker processes or serverless functions timing out repeatedly when processing specific PDF inputs
  • Growth in queued jobs for PDF processing services alongside stalled worker threads

Detection Strategies

  • Inventory Python environments and identify installations of pypdf below version 6.14.1 using pip list or SBOM tooling.
  • Add watchdog timers around calls to PdfReader, extract_text(), and related content stream parsing functions to abort runaway operations.
  • Scan stored PDFs for inline image operators lacking a matching EI marker as a preprocessing heuristic.

Monitoring Recommendations

  • Alert on Python worker processes exceeding CPU thresholds for longer than expected PDF processing durations.
  • Correlate document ingestion timeouts with the specific input files that triggered them to identify malicious samples.
  • Track pypdf package versions across containers and serverless functions in your software bill of materials.

How to Mitigate CVE-2026-59936

Immediate Actions Required

  • Upgrade pypdf to version 6.14.1 or later in all applications, containers, and virtual environments.
  • Pin the fixed version in requirements.txt, pyproject.toml, and lock files to prevent regression.
  • Enforce processing timeouts on any code path that parses PDFs from untrusted sources.
  • Rebuild and redeploy container images that bundle vulnerable pypdf versions.

Patch Information

The fix is available in pypdf6.14.1. See the GitHub Release 6.14.1, the GitHub Pull Request #3891, the commit ec3b1459, and the GitHub Security Advisory GHSA-5xf7-4p34-54qr for details.

Workarounds

  • Execute PDF parsing in isolated subprocesses with hard CPU and wall-clock limits so a single malicious file cannot exhaust the parent service.
  • Reject PDFs that fail structural validation before passing them to pypdf, filtering content streams with malformed inline image operators.
  • Run PDF ingestion workers behind a queue with per-job timeouts and automatic restart on hangs.
bash
# Upgrade pypdf to the patched release
pip install --upgrade 'pypdf>=6.14.1'

# Verify the installed version
python -c "import pypdf; print(pypdf.__version__)"

# Example: pin the fixed version in requirements.txt
echo 'pypdf>=6.14.1' >> requirements.txt

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.