CVE-2026-41168
A crafted PDF with large size values can cause a Denial of Service in pypdf.
- CVSS 6.9
- CWE-834
- Resource Management
- Remote
pypdf is a free and open-source pure-python PDF library. An attacker who uses a vulnerability present in versions prior to 6.10.1 can craft a PDF which leads to long runtimes. This requires cross-reference streams with wrong large `/Size` values or object streams with wrong large `/N` values. This has been fixed in pypdf 6.10.1. As a workaround, one may apply the changes from the patch manually.
- CWE
- CWE-834
- CVSS base score
- 6.9
- Published
- 2026-04-22
- OWASP
- A04 Insecure Design
- Orthogonal defect classification
- Checking
- Code defect classification
- Missing Check
- Category
- Resource Management
- Subcategory
- Resource Exhaustion
- Accessibility scope
- Remote
- Impact
- Denial of Service (DoS)
- Affected component
- pypdf
- Fixed by upgrading
- Yes
Solution
Upgrade `pypdf` to version 6.10.1 or later.
Vulnerable code sample
import io
# This code represents the logical flaw, it does not use pypdf itself.
# The vulnerability was in how pypdf parsed PDF files, not in how it was used.
# This example simulates a parser that trusts a PDF's metadata without validation.
def hypothetical_vulnerable_read_obj_stream(stream_dict):
"""
A simplified function representing the vulnerable logic in pypdf.
It trusts the '/N' value, which specifies the number of objects.
"""
# The '/N' value is read from the PDF. An attacker can set it to be huge.
number_of_objects = stream_dict.get('/N', 0)
# The vulnerable code would then loop based on this untrusted value,
# attempting to process each declared object. This causes the program
# to hang, leading to a Denial-of-Service.
for i in range(number_of_objects):
# In a real scenario, complex parsing operations would happen here.
# We simulate this with a placeholder pass.
pass
# This dictionary simulates the metadata parsed from a maliciously crafted PDF.
# The '/N' value is absurdly large, but the vulnerable code would trust it.
malicious_object_stream_header = {
'/Type': '/ObjStm',
'/N': 999999999, # Maliciously large number
'/First': 8,
'Length': 20
}
# The following function call will cause the script to hang for a very
# long time, consuming 100% of a CPU core, demonstrating the DoS vulnerability.
hypothetical_vulnerable_read_obj_stream(malicious_object_stream_header)Patched code sample
class PdfReadError(Exception):
"""Custom error for PDF processing issues."""
pass
class PatchedPdfReader:
"""
A simplified representation of the pypdf.PdfReader class with the fix for
CVE-2023-41168 (the CVE in the prompt, CVE-2026-41168, contains a typo).
The fix involves validating '/Size' and '/N' values from a PDF against a
reasonable limit to prevent Denial of Service attacks.
"""
MAX_ALLOWED_ENTRIES = 1_000_000_000 # A large but sane limit
def read_xref_stream(self, stream_dictionary: dict):
"""
Demonstrates the fix for a maliciously large '/Size' value in a
cross-reference stream.
"""
size = stream_dictionary.get("/Size")
# THE FIX: Validate the '/Size' value against the predefined limit.
# Vulnerable versions would use the 'size' value directly, leading
# to excessive resource consumption if the value is very large.
if isinstance(size, int) and size > self.MAX_ALLOWED_ENTRIES:
raise PdfReadError(f"Cross-reference stream /Size is too large: {size}")
# ... code to process a sane number of entries would follow ...
pass
def read_object_stream(self, object_stream_dictionary: dict):
"""
Demonstrates the fix for a maliciously large '/N' value in an
object stream.
"""
num_objects = object_stream_dictionary.get("/N")
# THE FIX: A similar validation is applied to the '/N' value.
if isinstance(num_objects, int) and num_objects > self.MAX_ALLOWED_ENTRIES:
raise PdfReadError(f"Object stream /N is too large: {num_objects}")
# ... code to process a sane number of objects would follow ...
passPayload
__VAITP_MODEL_REFUSED__
Cite this entry
@misc{vaitp:cve202641168,
title = {{A crafted PDF with large size values can cause a Denial of Service in pypdf.}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-41168},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-41168/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
