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

CVE-2026-71852: Denial of Service via Excessive Iteration and Memory Exhaustion in pypdf CID Font Parsing

Amit Schendel
Amit Schendel
Senior Security Researcher

Aug 7, 2026·7 min read·51 visits

Executive Summary (TL;DR)

Unconstrained CID font width expansion in pypdf leads to application hang and OOM crashes.

A Denial of Service (DoS) vulnerability exists in pypdf prior to version 6.15.0. When parsing maliciously crafted PDF files containing excessively large CID font width ranges, the library suffers from CPU starvation and memory exhaustion due to unconstrained loop expansion.

Vulnerability Overview

The library pypdf is a widely utilized open-source Python library for parsing, manipulating, and extracting content from PDF documents. It serves as a foundational component in numerous document-processing pipelines, search indexing systems, and data extraction backends. Because it processes complex, nested binary structures defined by untrusted external users, its parsing functions represent a significant attack surface.

This vulnerability, tracked as CVE-2026-71852, belongs to the class of CWE-834: Excessive Iteration. It resides specifically within the CID (Character Identifier) font width parser module, located in pypdf/_font.py. The flaw enables local or remote unauthenticated actors to trigger a denial of service condition.

The attack is executed by embedding a custom Font dictionary containing structurally anomalous CID widths. When the application attempts to process the font dictionaries during typical workflows like text extraction, the parser executes an unconstrained loop. This results in execution delays and memory allocation overhead.

Root Cause Analysis

The primary flaw stems from the implementation of the static method Font._collect_cid_character_widths() in pypdf/_font.py. This method is designed to parse the /W (Widths) array within a DescendantFont dictionary. According to the PDF specification, the /W array specifies character widths to facilitate accurate typographic rendering and text extraction.

The PDF specification defines two formats for width specifications. Format 1 provides a start character index followed by an array of individual glyph widths. Format 2 defines a starting index, an ending index, and a constant width that is applied uniformly across the entire range. In previous versions, the parser handled both formats by instantly expanding these ranges into a flat Python dictionary mapping each individual character index to its defined width.

The vulnerability is triggered because the parsing logic failed to validate the distance between the starting and ending indices. When encountering a Format 2 entry such as [ 1 200000000 120 ], the parser initializes a generator expression via the Python range() constructor spanning from 1 to 200,000,000. It then processes this range within a dictionary comprehension to populate the internal mapping. This design assumes all inputs are structurally valid and conform to reasonable bounds.

Due to the internal implementation of Python dictionary objects, which use hash tables, allocating millions of keys instantly consumes significant memory resources. The host operating system running the document processing service experiences memory exhaustion, resulting in an OOM termination. If the system has sufficient swap space to prevent an immediate crash, the CPU becomes completely occupied by the iteration, resulting in resource starvation.

Code Analysis

The vulnerability was remediated in the py-pdf/pypdf repository via commit 51cb6acf9e8a35b77e90b4d87d28fe3e1416d7d7. The changes isolate the unconstrained range expansion by implementing defensive thresholds based on the limits of standard typography.

Below is a comparison highlighting the critical code paths before and after the remediation was applied.

Pre-Patch Implementation (Vulnerable)

The following block shows the unvalidated dictionary updates for both format types:

# Format 1: Individual character widths mapping
# If len(width_list) is unchecked, it can trigger high loop counts.
current_widths.update(
    {
        chr(_cidx): _width
        for _cidx, _width in zip(
            range(
                cast(int, start_idx),
                cast(int, start_idx) + len(width_list),
                1,
            ),
            width_list,
        )
    }
)
 
# Format 2: Constant width range mapping
# High stop_idx values lead to excessive iteration.
current_widths.update(
    {
        chr(_cidx): const_width
        for _cidx in range(
            cast(int, start_idx), cast(int, stop_idx + 1), 1
        )
    }
)

Post-Patch Implementation (Remediated)

The patch defines strict structural limits to restrict range bounds to standard typographic constraints:

# Global constraints added to pypdf/_font.py
MAX_CID_WIDTH_ENTRY_COUNT = 65_536  # Standard limit for 16-bit CID spaces
MAX_WIDTH_ENTRY_COUNT = 100_000
 
@staticmethod
def __check_range_length(start: int, end: int) -> None:
    if end < start:
        raise LimitReachedError(
            f"Invalid CID width range: {start}..{end}."
        )
 
    count = end - start
    if count > MAX_CID_WIDTH_ENTRY_COUNT:
        raise LimitReachedError(f"CID width range too large: {count} > {MAX_CID_WIDTH_ENTRY_COUNT}.")
 
@staticmethod
def __check_entry_count(count: int) -> None:
    if count > MAX_WIDTH_ENTRY_COUNT:
        raise LimitReachedError(f"Too many character widths: {count} > {MAX_WIDTH_ENTRY_COUNT}.")

During execution, these functions assert limits prior to dictionary generation:

# Format 1 with range validation
start_idx, width_list = int(w_entry), w_next_entry
stop_idx = start_idx + len(width_list)
Font.__check_range_length(start_idx, stop_idx)
entry_count += (stop_idx - start_idx)
Font.__check_entry_count(entry_count)
 
# Format 2 with range validation
start_idx, stop_idx, const_width = (
    int(w_entry),
    int(w_next_entry),
    _w[idx + 2].get_object(),
)
Font.__check_range_length(start_idx, stop_idx + 1)
entry_count += (stop_idx - start_idx + 1)
Font.__check_entry_count(entry_count)

By asserting these limits, the software prevents the execution of large loops and blocks memory allocations that exceed predefined structural norms.

Exploitation Methodology

Exploitation of CVE-2026-71852 relies on creating a structural PDF file containing abnormal CID metrics within a descendant font object. Since the library processes font resources automatically when analyzing PDF pages, an attacker does not require special administrative access.

The attack path is visualized in the diagram below:

To configure a test case, an attacker creates a DescendantFont dictionary containing a /W array containing a large index span:

3 0 obj
<<
  /Type /Font
  /Subtype /CIDFontType2
  /BaseFont /CustomCIDFont
  /CIDSystemInfo << /Registry (Adobe) /Ordering (Identity) /Supplement 0 >>
  /W [ 0 100000000 1000 ]
>>
endobj

When this file is parsed via PdfReader('malicious.pdf') and any method attempting to parse page text is called, the library executes _collect_cid_character_widths(). The processing loop triggers CPU utilization and memory expansion, crashing the active process.

Impact Assessment

The primary impact of CVE-2026-71852 is localized Denial of Service (DoS). When a vulnerable application processes a crafted document, the Python engine allocates memory dynamically to accommodate the generated dictionary. This quickly exhausts system memory, triggering operating system-level process termination via the Out-of-Memory (OOM) killer.

In environments where auto-restart mechanisms are not configured, this termination results in a persistent denial of service state. For backend systems processing documents asynchronously (e.g., through a queue), the crash of worker processes can stall the entire pipeline, as the offending document is repeatedly picked up and re-processed.

The vulnerability is rated at a CVSS score of 4.8. Although the attack vector is local, the actual mechanism of delivery is frequently remote, such as uploading a file to a web application. Consequently, document processing utilities facing public-facing endpoints represent the primary area of exposure.

Remediation and Mitigation

The primary remediation strategy is upgrading the pypdf dependency to version 6.15.0 or higher. The maintainers resolved the issue by introducing the input size and bounds checks documented in commit 51cb6acf9e8a35b77e90b4d87d28fe3e1416d7d7.

To execute the upgrade via standard package managers, run the following command:

pip install --upgrade pypdf>=6.15.0

Where immediate upgrade is unfeasible, implement host-level resource constraints. Configure container limits inside runtime environments to prevent a single parsing thread from affecting surrounding system services:

# Example docker-compose resource limits
services:
  pdf-worker:
    image: pdf-processor:latest
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M

Additionally, apply maximum payload size constraints on incoming files to minimize resource footprint and restrict document processing execution time through application-level timeouts.

Patch Security Assessment & Potential Bypasses

An analysis of the remediation commit reveals potential security boundaries that developers and security administrators should monitor. The patch enforces the limits using a local counter variable, entry_count, which tracking elements during a single call to _collect_cid_character_widths().

Because the counter is initialized to 0 at the start of the function call, it does not maintain state across multiple font dictionary processing operations. If a document defines multiple /DescendantFonts in a single complex font resource, pypdf iterates over each descendant font sequentially. Each descendant font can populate up to 100,000 entries into the shared character_widths dictionary reference.

This design permits an attacker to define dozens of child font dictionaries, each carrying slightly less than the 100,000 limit. When merged, the final character_widths mapping can still reach dimensions that cause significant memory growth. Furthermore, developers should inspect equivalent mapping modules, such as vertical typographic specifications (/W2) and custom CMaps, to confirm that range expansions are subject to similar validations.

Fix Analysis (1)

Technical Appendix

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

Affected Systems

Any Python application or backend service utilizing pypdf versions prior to 6.15.0 to extract text, parse metadata, or merge PDF documents.

Affected Versions Detail

Product
Affected Versions
Fixed Version
pypdf
py-pdf
< 6.15.06.15.0
AttributeDetail
CWE IDCWE-834
Attack VectorLocal
CVSS v4.04.8
ImpactDenial of Service (DoS)
Exploit Statusnone
KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499Endpoint Denial of Service
Impact
CWE-834
Excessive Iteration

The software does not limit the number of times a loop or iteration can execute, allowing excessive resource consumption.

Vulnerability Timeline

Fix commit pushed to repository
2026-08-06
GitHub Security Advisory published
2026-08-07
CVE-2026-71852 assigned and published
2026-08-07
Version 6.15.0 released with complete remediation
2026-08-07

References & Sources

  • [1]https://github.com/py-pdf/pypdf/security/advisories/GHSA-fwg2-594c-jp42
  • [2]https://github.com/py-pdf/pypdf/pull/3946
  • [3]https://github.com/py-pdf/pypdf/commit/51cb6acf9e8a35b77e90b4d87d28fe3e1416d7d7
  • [4]https://github.com/py-pdf/pypdf/releases/tag/6.15.0
  • [5]https://www.cve.org/CVERecord?id=CVE-2026-71852

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

•18 minutes ago•CVE-2026-105749
6.5

CVE-2026-105749: Unbounded Table Attributes in Docling Backends Leads to Resource Exhaustion

An uncontrolled resource consumption vulnerability exists in the Docling document conversion library. Maliciously structured HTML, JATS, ODS, or BoxNote inputs containing table cells with excessively large 'rowspan' or 'colspan' attribute values trigger algorithmic complexity conditions. This allows unauthenticated remote attackers to initiate resource exhaustion states, crashing or hanging the target document processing pipeline while bypassing configured timeouts.

Amit Schendel
Amit Schendel
0 views•6 min read
•about 1 hour ago•CVE-2026-105748
4.3

CVE-2026-105748: Local File Inclusion and Arbitrary File Disclosure in Docling Document Parser

A Local File Inclusion (LFI) and Arbitrary File Disclosure vulnerability exists in Docling and Docling Slim versions >= 2.16.0 up to 2.131.0. When parsing serialized DoclingDocument structures using the JSON input format, the backend fails to restrict image URI schemes, allowing remote attackers to retrieve local files and verify path existence on the host system during embedded document export.

Amit Schendel
Amit Schendel
3 views•5 min read
•about 2 hours ago•CVE-2026-105744
7.5

CVE-2026-105744: Arbitrary File Read and Remote Code Execution in Docling Tectonic Engine

Docling, a tool for parsing and processing diverse document formats, is vulnerable to arbitrary file read, arbitrary file write, and potential remote code execution (RCE) in versions 2.94.0 through 2.131.0. The vulnerability occurs when applications configure Docling to use the Tectonic engine for rendering TikZ diagrams into images. Because the compilation did not restrict hazardous TeX primitives or sandbox the environment, an attacker can supply crafted documents containing malicious TikZ definitions to access or modify local files and execute arbitrary commands under the privileges of the processing application.

Amit Schendel
Amit Schendel
4 views•7 min read
•about 3 hours ago•CVE-2026-105743
4.0

CVE-2026-105743: Server-Side Request Forgery Guard Bypass in Docling Document Conversion Engine

An SSRF guard bypass vulnerability in the Docling document conversion engine allows unauthenticated attackers to bypass internal IP access controls. The vulnerability exists due to a DNS rebinding Time-of-Check Time-of-Use (TOCTOU) condition, URL authority parsing inconsistencies, and unvalidated network requests triggered during headless browser page rendering.

Amit Schendel
Amit Schendel
4 views•6 min read
•about 4 hours ago•CVE-2026-105742
3.7

CVE-2026-105742: Sensitive Custom Header Leakage in Docling Image Resource Loader

A technical analysis of CVE-2026-105742 (GHSA-p3fw-7699-7926), a sensitive information disclosure vulnerability in the Docling document processing library. Vulnerable versions of Docling indiscriminately forward custom HTTP headers, such as authentication tokens, to arbitrary third-party origins and during cross-origin redirects while fetching remote image assets from untrusted HTML and EPUB documents.

Alon Barad
Alon Barad
5 views•6 min read
•about 5 hours ago•CVE-2026-106121
4.9

CVE-2026-106121: Denial of Service via Infinite Loop in RabbitMQ Java Client JSON Parser

CVE-2026-106121 is a Denial of Service (DoS) vulnerability in the RabbitMQ Java Client library (amqp-client) affecting versions prior to 5.37.0. The vulnerability resides in the legacy, custom JSON-RPC parsing class com.rabbitmq.tools.json.JSONReader. When parsing malformed or truncated payloads ending within a quoted string or single-line comment, the parser's scanner enters an infinite loop. This occurs because the loop lacks an exit condition for the end-of-input sentinel character returned by the iterator, leading to either CPU exhaustion or a JVM crash from an OutOfMemoryError.

Amit Schendel
Amit Schendel
7 views•6 min read