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-113790

CVE-2026-113790: Uncontrolled Resource Consumption in pypdf Container Parsing

Alon Barad
Alon Barad
Software Engineer

Oct 23, 2026·5 min read·3 visits

Executive Summary (TL;DR)

pypdf versions prior to 6.21.0 lack upper element bounds and cumulative token limits when deserializing PDF arrays, dictionaries, and streams. Attackers can submit malformed PDFs to trigger high CPU usage and out-of-memory process crashes.

A Denial of Service (DoS) vulnerability in pypdf versions prior to 6.21.0 allows remote attackers to cause high CPU and memory resource exhaustion by supplying PDF files containing oversized or deeply nested arrays, dictionaries, or content streams.

Vulnerability Overview

The Python PDF manipulation library pypdf is susceptible to uncontrolled resource consumption (CWE-400 / CWE-770) during PDF container deserialization. Prior to version 6.21.0, the library processed primitive PDF container structures sequentially without verifying upper bounds on element counts or enforcing a global token budget.

PDF documents structure raw metadata and stream data into three core collection mechanisms: Arrays, Dictionaries, and Content Streams. When parsing these entities, pypdf eagerly allocated Python objects for every token encountered within stream boundaries. An attacker can construct a compact, highly compressed PDF containing millions of small elements to induce memory exhaustion or execution loops.

This flaw impacts web applications, background document pipelines, and API services that ingest untrusted PDF uploads using vulnerable pypdf releases.

Root Cause Analysis

The root cause resides in the token parsing logic implemented within ArrayObject.read_from_stream, DictionaryObject.read_from_stream, and ContentStream._parse_content_stream. The library assumed stream content was bounded implicitly by file length or decompressed stream limits.

During stream processing, the parser reads consecutive tokens and instantiates corresponding Python wrapper types (NumberObject, NameObject, BooleanObject, NullObject). Because Python object creation incurs per-instance memory overhead, dense token streams demand memory disproportionate to file size on disk.

> [!NOTE] > A PDF array containing 1,000,000 integer tokens requires minimal stream storage, but causes pypdf to allocate hundreds of megabytes of Python heap memory during deserialization.

Additionally, generic exception handlers inside structural parsing functions previously caught and suppressed underlying security exceptions. If a sub-routine encountered a parsing boundary error, the container parser suppressed the signal and continued consumption.

Code Analysis & Patch Inspection

In commit 18bd2981a74479483a0b9507602c58a63d6c9b12 (Pull Request #4218), maintainers implemented global token tracking and safety thresholds in pypdf/_configuration.py and pypdf/generic/_data_structures.py.

The patch introduces explicit collection caps alongside a shared, mutable budget context (StreamParsingBudget):

# pypdf/_configuration.py snippet
array_maximum_element_count: int = 100_000
dictionary_maximum_element_count: int = 100_000
stream_parsing_work_maximum_count: int = 2_000_000

The ArrayObject.read_from_stream method was modified to check remaining quotas before appending new elements:

# Patch diff in ArrayObject._check_limits
@staticmethod
def _check_limits(*, remaining_elements: int, parsing_budget: Optional[StreamParsingBudget]) -> int:
    remaining_elements -= 1
    if remaining_elements < 0:
        raise LimitReachedError("Reached maximum array element count.")
    if parsing_budget is not None:
        parsing_budget.remaining_budget -= 1
        if parsing_budget.remaining_budget < 0:
            raise LimitReachedError("Reached maximum number of tokens.")
    return remaining_elements

When LimitReachedError is raised, container parsers now propagate the exception directly rather than catching it in general exception handling clauses.

Exploitation Methodology

Exploitation requires sending a tailored PDF document to an application that invokes parsing methods on untrusted input. Authentication requirements depend entirely on the target application exposure.

An attacker constructs a document containing deeply nested collection structures or repetition patterns. For instance, a stream defining an array with millions of null tokens [ null null ... null ] causes pre-6.21.0 parsers to enter a long execution loop while repeatedly increasing heap memory usage.

%PDF-1.7
1 0 obj
<< /Type /Catalog /Pages 2 0 R >>
endobj
2 0 obj
<< /Type /Pages /Count 1 /Kids [3 0 R] >>
endobj
3 0 obj
<< /Type /Page /Parent 2 0 R /Contents 4 0 R >>
endobj
4 0 obj
<< /Length 50000 >>
stream
[ 0 0 0 0 ... <repeated 1,000,000 times> ... 0 ]
endstream
endobj

When the application attempts to inspect or extract text from page content streams, the thread parsing the stream exhausts available memory, leading to an Out-Of-Memory (OOM) process termination.

Security Impact Analysis

The security impact is restricted to application availability. Unauthenticated users can trigger service disruptions by uploading crafted PDF documents to public endpoints.

Because Python handles memory allocation at the process level, exhaustion in a multi-threaded web worker (such as Gunicorn or uWSGI workers) results in worker termination by system kernel OOM killers, causing service degradation or total application outage.

CVSS v4.0 evaluates this issue with a base score of 6.0 (CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N). No confidentiality or integrity violations occur, and execution context boundaries prevent remote code execution through this bug class.

Remediation & Defense Guidance

The primary remediation step is upgrading the pypdf dependency to version 6.21.0 or higher.

For applications requiring custom threshold definitions when handling untrusted documents, parameters can be customized dynamically using apply_configuration:

from pypdf import apply_configuration, PdfReader
from pypdf.errors import LimitReachedError
 
# Configure custom strict parsing limits
with apply_configuration(
    array_maximum_element_count=10_000,
    dictionary_maximum_element_count=10_000,
    stream_parsing_work_maximum_count=500_000
):
    try:
        reader = PdfReader("untrusted_document.pdf")
        text = reader.pages[0].extract_text()
    except LimitReachedError:
        # Gracefully drop or reject malformed inputs
        raise ValueError("Uploaded file exceeded maximum parsing limits")

Additionally, processing untrusted uploads inside isolated container environments with resource memory limits prevents host-wide Denial of Service.

Technical Appendix

CVSS Score
6.0/ 10
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N

Affected Systems

pypdf versions prior to 6.21.0Python web services and document processing pipelines ingesting untrusted PDF files via pypdf
AttributeDetail
CWE IDCWE-400 (Uncontrolled Resource Consumption)
CVSS v4.06.0 (Medium)
Attack VectorNetwork (AV:N)
EPSS Score0.00317 (23.44th percentile)
ImpactDenial of Service (High Memory / CPU Resource Exhaustion)
Exploit StatusProof of Concept / Test Suite Code Available
CISA KEV StatusNot Listed
CWE-400
Uncontrolled Resource Consumption

More Reports

•11 minutes ago•CVE-2026-115477
7.1

CVE-2026-115477: Human-in-the-Loop Authorization Bypass in obsidian-tc

A high-severity authorization bypass vulnerability in obsidian-tc allows clients to bypass Human-In-The-Loop (HITL) confirmation prompts over Streamable HTTP deployments. Due to incomplete validation of returned prompt responses, an attacker echoing a signed requestState token can force execution of destructive vault operations even if a human user declines or cancels the prompt.

Alon Barad
Alon Barad
1 views•5 min read
•about 2 hours ago•CVE-2026-113789
6.0

CVE-2026-113789: Algorithmic Complexity and Resource Exhaustion in pypdf Interactive Form Parsing

An uncontrolled resource consumption and inefficient algorithmic complexity vulnerability in pypdf prior to version 6.21.0 allows remote attackers to trigger application-level denial-of-service (DoS) via crafted PDF form field hierarchies.

Alon Barad
Alon Barad
4 views•5 min read
•about 3 hours ago•CVE-2026-114131
6.5

CVE-2026-114131: Nuxt Route Rules appMiddleware Bypass via Percent-Encoded Route Segments

Nuxt versions 3.11.0 through 3.21.3 and 4.0.0 through 4.4.3 contain an interpretation conflict between the route rules matching engine and the core page routing mechanism. By submitting percent-encoded request path segments, unauthenticated attackers can bypass route rules, including appMiddleware authorization guards, and access rendered server-side page payloads.

Amit Schendel
Amit Schendel
4 views•5 min read
•about 4 hours ago•CVE-2026-114130
2.3

CVE-2026-114130: Cross-Site Scripting via ASCII Control Characters in Nuxt Fallback Router

A Cross-Site Scripting (XSS) vulnerability exists in Nuxt when configured with pages disabled (pages: false). ASCII C0 control characters prefixing javascript: URIs bypass internal protocol classification in the fallback router, allowing unauthenticated attackers to execute arbitrary script in the victim's origin context upon user interaction.

Alon Barad
Alon Barad
5 views•5 min read
•about 5 hours ago•CVE-2026-114133
5.4

CVE-2026-114133: Stored Cross-Site Scripting via useHeadSafe in Nuxt Server Islands

A Stored Cross-Site Scripting (XSS) vulnerability exists in Nuxt Server Island rendering logic when utilizing the useHeadSafe composable. Raw head attributes bypass sanitization during island serialization.

Amit Schendel
Amit Schendel
4 views•4 min read
•about 6 hours ago•CVE-2026-114132
6.3

CVE-2026-114132: Case-Sensitivity Route Rule Bypass in Nuxt Framework

Nuxt versions prior to 4.6.2 suffer from a route rule bypass vulnerability caused by an architectural mismatch in case-sensitivity handling between the Nitro server runtime and the Vue page router. An unauthenticated remote attacker can bypass server-enforced route directives—such as redirects, security headers, and SSR controls—by altering character casing in HTTP request paths.

Amit Schendel
Amit Schendel
4 views•6 min read