CVE-2026-59938 Overview
CVE-2026-59938 is a memory exhaustion vulnerability in pypdf, a widely used pure-Python PDF library. Versions prior to 6.14.0 fail to validate declared image dimensions against actual image data during PDF parsing. An attacker can craft a PDF that declares oversized image dimensions, causing pypdf to allocate excessive memory when processing the image. The underlying weakness is classified as [CWE-789: Memory Allocation with Excessive Size Value]. Any application or service that parses untrusted PDF documents with pypdf is exposed to remote denial-of-service conditions. The issue is fixed in pypdf version 6.14.0.
Critical Impact
Attackers can trigger uncontrolled memory allocation in pypdf by supplying a malicious PDF, leading to denial of service against document-processing pipelines.
Affected Products
- pypdf versions prior to 6.14.0
- Python applications and services that parse untrusted PDF files with pypdf
- Document-processing pipelines, PDF ingestion APIs, and OCR workflows built on pypdf
Discovery Timeline
- 2026-07-08 - CVE-2026-59938 published to NVD
- 2026-07-09 - Last updated in NVD database
Technical Details for CVE-2026-59938
Vulnerability Analysis
The vulnerability resides in pypdf's image parsing path. When pypdf decodes an image XObject embedded in a PDF, it trusts the declared image dimensions (width × height) and the color mode when constructing the pixel buffer. A crafted PDF can declare very large dimensions while providing only a small compressed data stream. During reconstruction, pypdf computes a required buffer size based on the attacker-controlled values and attempts to materialize a Pillow Image object of that size. This produces a large memory allocation that can exhaust available RAM on the host. The flaw is a resource-consumption issue [CWE-789] rather than a memory-corruption bug, and it does not require authentication or user interaction beyond supplying a PDF for processing.
Root Cause
The root cause is missing validation of declared image size before allocation in _image_from_bytes within pypdf/generic/_image_xobject.py. Prior to the patch, the function passed attacker-controlled size and mode values directly to Image.frombytes and, in the fallback path, computed a byte-replication factor k = nb_pix * len(mode) / data_length without bounding the total buffer size. Because no upper limit was enforced on pixel_count * bytes_per_pixel, an adversary could specify arbitrarily large images.
Attack Vector
Exploitation requires an attacker to deliver a crafted PDF to any component that parses it with a vulnerable version of pypdf. Common exposure points include web upload endpoints, email attachment scanners, PDF-to-text services, and automated report ingestion. Because the attack vector is network-reachable and requires no privileges, unattended server-side parsing is the highest-risk scenario. Successful exploitation manifests as memory exhaustion, worker crashes, and degradation or outage of the hosting service.
# Patch excerpt from pypdf/generic/_image_xobject.py
# Source: https://github.com/py-pdf/pypdf/commit/c64583be16b8e8763d8777075f8ecbf382014b7a
def _image_from_bytes(
mode: str, size: tuple[int, int], data: bytes
) -> Image.Image:
pixel_count = size[0] * size[1]
bytes_per_pixel = len(mode)
required_byte_count = pixel_count * bytes_per_pixel
from pypdf.filters import FLATE_MAX_BUFFER_SIZE # noqa: PLC0415
if required_byte_count > FLATE_MAX_BUFFER_SIZE:
raise LimitReachedError(
f"Requested image buffer size {required_byte_count} exceeds limit {FLATE_MAX_BUFFER_SIZE}."
)
try:
img = Image.frombytes(mode, size, data)
except ValueError as exc:
data_length = len(data)
if data_length == 0:
raise EmptyImageDataError(
"Data is 0 bytes, cannot process an image from empty data."
) from exc
if data_length % pixel_count != 0:
raise
k = required_byte_count / data_length
data = b"".join(bytes((x,) * int(k)) for x in data)
img = Image.frombytes(mode, size, data)
return img
The patch enforces FLATE_MAX_BUFFER_SIZE (75,000,000 bytes) as an upper bound on requested image size and raises LimitReachedError before allocation occurs. Source: pypdf commit c64583b.
Detection Methods for CVE-2026-59938
Indicators of Compromise
- Python worker processes hosting pypdf terminated by the OS out-of-memory killer shortly after PDF ingestion.
- Unhandled exceptions or tracebacks originating in pypdf/generic/_image_xobject.py or pypdf/filters.py during document processing.
- Sudden spikes in resident memory usage of PDF-parsing services correlated with specific inbound documents.
Detection Strategies
- Inventory Python dependencies across build artifacts and container images to identify pypdf versions below 6.14.0.
- Inspect PDF image XObjects for implausibly large /Width and /Height values relative to the size of the compressed stream.
- Correlate application error logs referencing MemoryError, Image.frombytes, or LimitReachedError with document upload events.
Monitoring Recommendations
- Alert on rapid memory growth or OOM terminations in services that parse user-supplied PDFs.
- Log and rate-limit PDF uploads by source, and record file hashes for post-incident analysis.
- Track pypdf version drift in software bill of materials (SBOM) reports across your fleet.
How to Mitigate CVE-2026-59938
Immediate Actions Required
- Upgrade pypdf to version 6.14.0 or later in all applications, containers, and virtual environments.
- Pin the minimum version in requirements.txt, pyproject.toml, or Poetry lockfiles to prevent regression.
- Rebuild and redeploy any container images that bundle pypdf as a transitive dependency.
Patch Information
The fix is included in pypdf6.14.0, which introduces a hard limit of 75,000,000 bytes on the requested image buffer size and raises LimitReachedError when a PDF declares a larger allocation. Details are available in the pypdf 6.14.0 release notes, the GitHub Security Advisory GHSA-5qjq-93h5-hrgp, and pull request #3888.
Workarounds
- Run PDF parsing in isolated worker processes with strict memory cgroups or ulimit caps to contain exhaustion.
- Reject PDFs exceeding a reasonable maximum file size at the ingress layer before they reach pypdf.
- Pre-validate PDFs with a lightweight parser to filter documents declaring absurd image dimensions.
# Upgrade pypdf to the patched release
pip install --upgrade "pypdf>=6.14.0"
# Verify the installed version
python -c "import pypdf; print(pypdf.__version__)"
# Example dependency pin
# requirements.txt
# pypdf>=6.14.0
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

