CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-59937

CVE-2026-59937: CPU Exhaustion via Quadratic-Time Cross-Reference Recovery Loop in pypdf

Alon Barad
Alon Barad
Software Engineer

Jul 23, 2026·4 min read·3 visits

Executive Summary (TL;DR)

pypdf versions prior to 6.14.0 are vulnerable to denial of service (CPU exhaustion) when parsing crafted PDFs containing thousands of malformed xref table entries due to an O(N*M) sequential regex recovery loop.

A critical CPU exhaustion vulnerability exists in the pypdf library before version 6.14.0. When parsing PDF files with malformed or corrupt standard cross-reference (xref) table entries, the library falls back to sequentially scanning the entire file buffer via regular expression search. An attacker can exploit this algorithmic bottleneck by supplying a crafted PDF with numerous malformed xref entries, leading to denial of service.

Vulnerability Overview

The pypdf library is a pure-Python library designed for splitting, merging, cropping, and transforming PDF files. It is heavily used in automated backend document processing pipelines, web applications supporting user-uploaded files, and data extraction engines.\n\nThis vulnerability exposes a denial-of-service vector through the parsing of cross-reference (xref) tables. When standard parsing fails due to invalid formatting or corrupted entries, the library triggers an automated recovery routine.\n\nThe recovery routine employs an inefficient algorithm that scales quadratically with respect to the number of invalid entries and the file buffer size. By executing multiple regex searches across the entire remaining stream buffer, a remote unauthenticated attacker can exhaust CPU resources on the hosting application.

Root Cause Analysis

The core flaw lies within the _read_standard_xref_table method inside pypdf/_reader.py. Standard PDF specifications state that the cross-reference table matches object numbers to their physical byte offsets, permitting rapid lookup.\n\nIn corrupted files, the entry fields may contain unexpected or corrupt formatting characters. To prevent immediate processing failures, the parser executes a recovery loop that sequentially scans the file stream to extract the actual byte coordinates of the target object.\n\nDuring each loop iteration, the parser calls re.search over the entire remaining file buffer buf of size $M$. If the table specifies $N$ corrupt entries, the system performs $N$ regex scans over the buffer of size $M$. This results in a time complexity of $O(N \times M)$, causing extreme thread blockages and high CPU utilization.

Code Analysis

The vulnerable logic in pypdf/_reader.py processes entries inside a persistent parsing loop. When a corrupt entry is identified, it repeatedly reads the remaining stream and runs a regex match to find the actual PDF object location.\n\npython\n# Vulnerable recovery fallback in pypdf/_reader.py\nbuf = stream.read(-1)\nstream.seek(p)\n\nf = re.search(rf\"{num}\\s+(\\d+)\\s+obj\".encode(), buf)\nif f is None:\n # Log missing object\nelse:\n generation = int(f.group(1))\n offset = f.start()\n\n\nThe patched implementation solves this structural problem by loading an in-memory dictionary-based cache exactly once when the first recovery is required. Lookups thereafter operate in constant $O(1)$ complexity.\n\npython\n# Patched logic utilizing a single-pass recovery cache\nif recovery_cache is None:\n recovery_cache = self._load_recovery_cache(buf)\n\nif num not in recovery_cache:\n # Log missing object\nelse:\n generation, offset = recovery_cache[num]\n\n\nThis change reduces the programmatic complexity of the recovery sequence from quadratic $O(N \times M)$ down to linear $O(N + M)$ execution complexity.

Exploitation

An attacker can exploit this behavior by sending a minimized PDF with a custom xref table. The table declares a high number of entries (e.g., 20,000) followed by sequential lines of corrupted ASCII characters like xxxxxxxxxxxxxxxx 0\\r\\n.\n\nBecause the parser tries to gracefully recover each declared entry, it executes the regex engine repeatedly. This causes the CPU core handling the parse job to spike to 100% capacity for an extended duration.\n\nBelow is a conceptual data flow diagram of the vulnerability execution:\n\nmermaid\ngraph LR\n A[\"Malformed PDF Payload\"] --> B[\"pypdf Reader Parse\"]\n B --> C[\"Read Standard XRef Table\"]\n C --> D{\"Entry Corrupt?\"}\n D -- \"Yes (N entries)\" --> E[\"Sequential Regex Scan on Buffer (M bytes)\"]\n E --> F[\"Repeat N times: O(N * M) Complexity\"]\n F --> G[\"CPU Exhaustion / Thread Freeze\"]\n D -- \"No\" --> H[\"Normal Processing\"]\n

Impact Assessment

The primary security consequence of CVE-2026-59937 is local or remote denial of service. For architectures deploying pypdf on synchronous web application workers, processing a single payload can completely lock a worker process, preventing it from handling legitimate web traffic.\n\nIf multiple malicious payloads are processed concurrently, the entire system can quickly exhaust its available CPU capacity, resulting in system-wide degradation or outages.\n\nWhile this vulnerability does not allow remote code execution or data extraction, its low attack complexity and high impact on system availability yield a CVSS score of 7.5. Applications that permit anonymous file uploads are especially vulnerable to this denial of service attack.

Remediation

The definitive fix is upgrading to pypdf version 6.14.0 or above. This version implements the single-pass cache system which neutralizes the algorithmic bottleneck.\n\nIf upgrading is not immediately possible, security teams should implement defensive file-processing controls. Restricting the maximum size of uploaded PDF files (e.g., keeping $M$ small) limits the impact of the sequential scans.\n\nAdditionally, wrapping PDF parsing calls in isolated subprocesses with explicit execution timeouts will terminate runaway parsing threads before they cause broad infrastructure issues.

Official Patches

py-pdfAdvisory and Remediation

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
EPSS Probability
0.34%
Top 73% most exploited
4,500
via Shodan

Affected Systems

Applications parsing user-supplied PDF documents using pypdf versions < 6.14.0Automated Python-based document processing pipelines

Affected Versions Detail

Product
Affected Versions
Fixed Version
pypdf
py-pdf
< 6.14.06.14.0
AttributeDetail
CWE IDCWE-400
Attack VectorNetwork (AV:N)
CVSS Score7.5 (High)
EPSS Score0.00345 (0.345%)
ImpactDenial of Service (DoS) via CPU Exhaustion
Exploit StatusPoC (Proof of Concept) available
KEV StatusNot listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-400
Uncontrolled Resource Consumption

The software does not properly control the allocation and maintenance of a limited resource on behalf of an actor, enabling an actor to influence the amount of resources consumed.

Known Exploits & Detection

GitHub Security Advisoryhttps://github.com/py-pdf/pypdf/security/advisories/GHSA-55h5-xmcq-c37v

Vulnerability Timeline

Vulnerability identified and patch structured
2026-06-17
Patch merged under PR #3887 and Version 6.14.0 released
2026-06-22
Security Advisory and CVE published
2026-07-08

References & Sources

  • [1]GitHub Security Advisory
  • [2]Pull Request #3887
  • [3]Fix Commit
  • [4]Release Notes v6.14.0
  • [5]CVE Record
  • [6]NVD Entry

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•14 minutes ago•CVE-2026-59936
8.7

CVE-2026-59936: Infinite Loop in pypdf Inline Image Parser Leads to Denial of Service

An infinite loop vulnerability exists in the pure-python PDF library pypdf prior to version 6.14.1. This vulnerability occurs during the processing of malformed or truncated page content streams containing inline images. Specifically, the parser fails to validate the End-of-Stream condition during inline image dictionary parsing. This results in continuous backward stream-seeking and an infinite loop that consumes 100% CPU on the processing thread.

Alon Barad
Alon Barad
1 views•6 min read
•about 1 hour ago•CVE-2026-59935
8.7

CVE-2026-59935: Infinite Loop Denial of Service in pypdf via Malformed Inline Images

An infinite loop vulnerability exists in the pypdf library prior to version 6.14.2 when processing malformed PDF inline images that utilize ASCII85 or ASCIIHex decoders. Attackers can exploit this vulnerability by submitting crafted PDF files containing incomplete streams, causing the parsing thread to consume 100% CPU resource indefinitely and leading to Denial of Service.

Amit Schendel
Amit Schendel
3 views•7 min read
•about 3 hours ago•GHSA-8FPG-XM3F-6CX3
7.4

GHSA-8FPG-XM3F-6CX3: Authentication Fail-Open via Unvalidated Server Responses in Auth.js

In Auth.js (specifically next-auth version 5), server-side configuration errors or backend exceptions can cause existence-based authentication and authorization checks to fail open. When the underlying core engine (@auth/core) encounters a configuration error or runtime exception, it returns an HTTP 500 Internal Server Error response containing a JSON-formatted error description payload. Prior to the fix, the next-auth wrappers read this response body using response.json() without validating the HTTP status code. Because any parsed JavaScript object evaluates to truthy, common existence-based checks incorrectly evaluated to true, letting unauthenticated requests pass.

Alon Barad
Alon Barad
3 views•7 min read
•about 5 hours ago•CVE-2026-6790
5.3

CVE-2026-6790: Host/Authority Header Desynchronization in Eclipse Jetty

A host/authority desynchronization vulnerability exists in Eclipse Jetty's handling of HTTP/2 and HTTP/3 requests. When both an ':authority' pseudo-header and a standard 'Host' header are present in a request, Jetty fails to validate that they represent the same target host. This desynchronization creates a host-confusion or 'split-brain' state, enabling attackers to bypass access control lists, escape virtual host isolation, poison web caches, or manipulate redirect targets in backend applications.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 6 hours ago•CVE-2026-8384
5.3

CVE-2026-8384: URI Path Parameter Parser State-Desynchronization Path Traversal in Eclipse Jetty

A path traversal vulnerability exists in Eclipse Jetty due to a state-desynchronization defect in the URI parsing state machine inside URIUtil.java. This defect allows unauthenticated remote attackers to bypass path-based security constraints enforced by downstream filters, application gateways, or authorization modules by crafting URIs with path parameter delimiters and parent directory traversal sequences.

Amit Schendel
Amit Schendel
5 views•7 min read
•about 7 hours ago•GHSA-WHVH-WF3X-G77J
0.0

GHSA-WHVH-WF3X-G77J: Improper Access Control and Listing Bypass in JupyterLab Extension Manager

An improper access control vulnerability in JupyterLab allows programmatic installation of blocked or non-allowed extensions. The vulnerability is caused by a missing await keyword when invoking the asynchronous checking method, leading Python to evaluate the returned coroutine object as truthy. Furthermore, the check lacks proper canonicalization of package names, enabling an attacker to bypass blocklists using casing or character variants.

Amit Schendel
Amit Schendel
6 views•6 min read