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

CVE-2026-59203: Denial of Service via Infinite Loop in Pillow EPS Image Parser

Amit Schendel
Amit Schendel
Senior Security Researcher

Jul 21, 2026·6 min read·16 visits

Executive Summary (TL;DR)

Unvalidated negative byte counts in Pillow's EPS image parser trigger an infinite backward stream-seek loop, resulting in 100% CPU utilization and application hang without requiring image rendering or a Ghostscript installation.

A denial-of-service (DoS) vulnerability in Pillow (Python Imaging Library) versions 12.0.0 through 12.2.0 allows unauthenticated remote attackers to trigger 100% CPU utilization and hang the processing thread. The issue occurs within the Encapsulated PostScript (EPS) image parser (PIL/EpsImagePlugin.py) due to missing validation on the byte count parsed from %%BeginBinary: comments, allowing negative values to cause an infinite backward stream seek loop. This formatting-level state-looping issue occurs during the initial format sniffing phase inside Image.open() and does not require the system Ghostscript interpreter to be executed or present. It is resolved in version 12.3.0.

Vulnerability Overview

Pillow incorporates a dedicated module to parse Encapsulated PostScript (EPS) files. This parser, located in PIL/EpsImagePlugin.py, processes PostScript files to read metadata and extract preview images. When an application attempts to process an incoming image via Image.open(), Pillow runs auto-detection routines to match the file against known image headers, meaning the EPS parser is triggered automatically upon encountering EPS-specific magic bytes.

Due to a lack of input validation in the parser's logic for processing Document Structuring Conventions (DSC) comments, the parser can be forced into an infinite loop state. This vulnerability class maps directly to CWE-835: Loop with Unreachable Exit Condition ('Infinite Loop').

An unauthenticated remote attacker can exploit this vulnerability to consume 100% CPU resource allocations on the application server. Because the flaw is executed during the format sniffing stage, it is processed before rendering, meaning the attack requires minimal compute cost for the attacker and is highly effective at exhausting single-threaded application workers.

Root Cause Analysis

The root cause of CVE-2026-59203 resides within the parsing of the %%BeginBinary: <bytecount> DSC comment directive inside PIL/EpsImagePlugin.py. According to the Adobe PostScript Document Structuring Conventions, the %%BeginBinary: directive specifies that a designated number of bytes of raw binary data follows immediately. The parser reads the integer string following this header to determine how many bytes to skip forward to bypass the binary segment.

The vulnerable implementation uses the statement self.fp.seek(bytecount, os.SEEK_CUR) to perform a relative forward seek from the current file pointer position. However, the parser does not enforce validation checks to guarantee that the converted bytecount integer is a non-negative value.

When a negative integer is supplied as the byte count (such as %%BeginBinary:-21), the seek operation is executed with a negative value, triggering a backward relative seek. The file pointer is repositioned to a point prior to the %%BeginBinary: directive line. During the subsequent iteration of the line-reading loop, the parser processes the exact same line again, creating an infinite loop that isolates execution within the thread, leading to total thread lockup and CPU exhaustion.

Code-Level Analysis and Patch Review

To understand the technical structure of the vulnerability, examine the parsing loop in the vulnerable version of PIL/EpsImagePlugin.py. The parser reads blocks of data from the file stream and checks the leading characters of the slice against known DSC comment headers:

# Vulnerable implementation prior to Pillow 12.3.0
elif bytes_mv[:14] == b"%%BeginBinary:":
    bytecount = int(byte_arr[14:bytes_read])
    self.fp.seek(bytecount, os.SEEK_CUR)

In this sequence, bytecount is derived directly from user-controlled input without bounds or sign checking. The file object pointer (self.fp) is shifted backward relative to its current position when bytecount is negative.

The patch implemented in Pillow 12.3.0 resolves this logical loophole by checking if the evaluated integer is less than zero. If the constraint check fails, a ValueError is raised, immediately terminating the file parsing sequence and avoiding the seek operation:

# Patched implementation in Pillow 12.3.0
elif bytes_mv[:14] == b"%%BeginBinary:":
    bytecount = int(byte_arr[14:bytes_read])
    if bytecount < 0:
        msg = "BeginBinary bytecount cannot be negative"
        raise ValueError(msg)
    self.fp.seek(bytecount, os.SEEK_CUR)

This validation mechanism is highly robust because it halts execution before any offset modifications occur on the file stream, preventing infinite iteration. The fix is considered complete as there are no other relative seek calls on raw user-controlled integers in this parsing scope.

Exploitation and Attack Methodology

Exploitation of CVE-2026-59203 is trivial and requires zero special privileges or system configurations. An attacker merely needs to submit a file containing a valid EPS header and a negative %%BeginBinary value to an endpoint that processes user uploads through Pillow. Because format verification is content-based, renaming the malicious EPS payload to .png or .jpg does not neutralize the vector; Pillow still routes the input stream to the vulnerable EPS parser.

The minimal payload structure contains standard PostScript headers to satisfy initial format detection, immediately followed by the malformed directive:

%!PS-Adobe-3.0 EPSF-3.0
%%BoundingBox: 0 0 100 100
%%BeginBinary:-21

Below is a conceptual Mermaid flow diagram showing how the file stream pointer is trapped inside the backward-seeking loop:

When the application processes this payload, the thread hosting the processing task enters a tight loop, driving its CPU usage to 100%. In single-threaded synchronous architectures, this denies service to all concurrent users instantly.

Impact Assessment and Threat Modeling

The impact of this vulnerability is characterized primarily by application-level denial of service. The CVSS v3.1 base score is calculated at 5.3 (Medium), with a low impact on availability. This CVSS classification assumes a localized process impact; however, in standard production architectures handling synchronous image resizing, multiple uploads of this payload can easily lock up all available workers, culminating in an application-wide outage.

Because the vulnerability is triggered during the format sniffing step, the code path is executed inside Image.open(). This eliminates the prerequisite for the actual image to be loaded or rendered via Image.load(). Furthermore, it completely bypasses the requirement for the host environment to have Ghostscript installed, making the attack highly reliable across standard Python containerized environments.

As of mid-2026, there are no documented instances of active exploitation in the wild, placing the Exploit Maturity at the Proof-of-Concept (PoC) stage. Due to the minimal complexity required to produce a functional exploit payload, detection and prevention at the perimeter are highly recommended.

Detection, Remediation, and WAF Implementation

The primary remediation path is upgrading the Python environment to utilize Pillow version 12.3.0 or later, which correctly sanitizes the %%BeginBinary directive integer. If an immediate upgrade is unfeasible, developers should restrict the list of allowed image types passed to Pillow during image loading. Bypassing automatic format sniffing stops the EPS parser from executing:

# Safe file-handling configuration
img = Image.open(user_file, formats=["PNG", "JPEG", "WEBP"])

Additionally, network and application administrators can configure Web Application Firewalls (WAF) or intrusion detection signatures to block or flag incoming files matching the malformed EPS byte footprint. A custom ModSecurity WAF rule can be drafted to detect files containing the malicious sequence:

SecRule REQUEST_BODY "(?i)%%BeginBinary:\\s*-\\d+" "id:1000001,phase:2,deny,status:400,msg:'Blocked suspected CVE-2026-59203 exploit attempt'"

For local file systems or upload processing pipelines, security teams can employ the YARA rule supplied in this report to continuously monitor for the presence of malformed vector files containing negative bytecounts.

Official Patches

python-pillowFix Commit
python-pillowVendor Security Advisory

Fix Analysis (1)

Technical Appendix

CVSS Score
5.3/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
EPSS Probability
0.39%
Top 69% most exploited

Affected Systems

Pillow (python-pillow) version 12.0.0 through 12.2.0

Affected Versions Detail

Product
Affected Versions
Fixed Version
Pillow
python-pillow
>= 12.0.0, < 12.3.012.3.0
AttributeDetail
CWE IDCWE-835: Loop with Unreachable Exit Condition ('Infinite Loop')
Attack VectorNetwork (AV:N)
CVSS v3.1 Score5.3 (Medium)
EPSS Score0.0039 (Percentile: 31.40%)
ImpactDenial of Service (Thread Hang / CPU Exhaustion)
Exploit StatusProof-of-Concept (PoC) available
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1499.004Endpoint Denial of Service: Application Exhaustion Flood
Impact
CWE-835
Loop with Unreachable Exit Condition ('Infinite Loop')

The program contains an iteration loop with an exit condition that cannot be met, causing it to loop forever.

Known Exploits & Detection

GitHub Security AdvisoryAdvisory containing technical description and proof of concept behavior.

Vulnerability Timeline

Patch proposed and merged into main Pillow branch via Pull Request #9708
2026-06-22
Pillow 12.3.0 released and GHSA-pg7v-jwj7-p798 advisory published
2026-07-14
NVD CVE-2026-59203 record fully mapped and published
2026-07-15

References & Sources

  • [1]GitHub Security Advisory GHSA-pg7v-jwj7-p798
  • [2]Fix Commit
  • [3]Pillow Pull Request #9708
  • [4]Pillow Release 12.3.0
  • [5]CVE Record on CVE.org
  • [6]NVD CVE-2026-59203

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

•10 minutes ago•GHSA-8RW6-P7M8-63JP
6.5

GHSA-8RW6-P7M8-63JP: Array Element-Level SELECT Permissions Leak in SurrealDB

SurrealDB versions supporting element-level SELECT permissions on arrays are vulnerable to a logical authorization bypass. Due to an index-shifting error during array filtration, restricted elements can skip permission checks and leak to unauthorized record users.

Alon Barad
Alon Barad
0 views•6 min read
•about 22 hours ago•CVE-2026-12243
7.5

CVE-2026-12243: Incomplete Path Traversal Validation and Percent-Encoding Bypass in NLTK

CVE-2026-12243 is a path traversal vulnerability in the Natural Language Toolkit (NLTK) version 3.9.4. The flaw exists because the input validation routine fails to account for percent-encoded directory traversal sequences like '..%2f' before passing them to urllib.request.url2pathname(), which decodes them into active traversal sequences.

Amit Schendel
Amit Schendel
5 views•8 min read
•about 23 hours ago•CVE-2026-73654
8.5

CVE-2026-73654: Prototype Pollution in Trigger.dev leading to Cascading Denial of Service

CVE-2026-73654 is a high-severity prototype pollution vulnerability in Trigger.dev. The flaw occurs during the handling of run-metadata updates through the PUT /api/v1/runs/:runId/metadata endpoint. Because user-supplied keys are parsed directly by the @jsonhero/path library without sanitization, an authenticated attacker with low privileges can pollute the global Object.prototype. This causes database queries via Prisma ORM to fail validation and induces unhandled exceptions in the Prometheus metrics client, resulting in a process-wide denial of service.

Alon Barad
Alon Barad
11 views•6 min read
•1 day ago•CVE-2026-73559
6.5

CVE-2026-73559: Uncontrolled Resource Consumption in vLLM API completions

CVE-2026-73559 is an uncontrolled resource consumption vulnerability in the vLLM engine, specifically within the /v1/completions API endpoint, allowing authenticated attackers to cause application-level denial of service via unbounded prompt arrays.

Amit Schendel
Amit Schendel
10 views•5 min read
•1 day ago•CVE-2026-54526
9.9

CVE-2026-54526: Strict Template Referencing Bypass and Privilege Escalation in Argo Workflows

A critical security bypass vulnerability in Argo Workflows allows authenticated attackers with workflow submission privileges to bypass 'Strict' or 'Secure' template referencing restrictions. By injecting unvalidated fields into the nested ArtifactGC configuration, attackers can execute arbitrary pod patches, leading to host namespace escape and cluster-wide privilege escalation.

Alon Barad
Alon Barad
15 views•6 min read
•1 day ago•CVE-2026-54249
6.8

CVE-2026-54249: Server-Side Request Forgery via Confused Deputy in Pydantic AI UI Adapters

A Server-Side Request Forgery (SSRF) / Confused Deputy vulnerability has been identified in Pydantic AI UI Adapters (such as VercelAIAdapter). Under certain conditions, a malicious client can supply manipulated message history with provider metadata that forces the server to resolve files within privileged cloud environments (AWS S3, Google Cloud Storage) or model providers. This occurs because the adapters deserialize client-provided metadata structures directly into UploadedFile instances without validation, which are subsequently fetched using high-privilege server credentials.

Alon Barad
Alon Barad
7 views•7 min read