high · 7.5CVE-2026-55620Aug 25, 2026

CVE-2026-55620: eml_parser ReDoS via Deeply Nested Parentheses in Received Headers

Rohit Hatagale
AI Security Researcher, SecureLayer7

A crafted EML file with thousands of nested parentheses in a Received header can pin a CPU core for several seconds, making email-processing pipelines vulnerable to denial of service.

Packageeml_parser
Ecosystempip
Affected< 3.0.2
Fixed in3.0.2
CVE-2026-55620: eml_parser ReDoS via Deeply Nested Parentheses in Received Headers

The problem

eml_parser strips CFWS (comment / folding whitespace) comments from Received: headers using a regex-based fix-point loop. Each iteration of the loop removes one layer of parentheses, so stripping N nested layers requires N regex passes over the whole string.

This gives the loop O(N²) time complexity in the nesting depth. According to the advisory, a single Received: header with 5,000 nested parentheses causes roughly 1.3 seconds of CPU saturation per parsed message, and runtime quadruples with each doubling of nesting depth.

Any service that accepts attacker-supplied EML files is exposed.

Proof of concept

A working proof-of-concept for CVE-2026-55620 in eml_parser, with the exact payload below.

text
From: attacker@evil.example
To: victim@target.example
Subject: DoS PoC
Received: from evil.example by target.example; Mon, 25 Aug 2026 00:00:00 +0000
 ((((((((((((((((((((((((((((((((((((((((((((((((((
 (((((((((((((((((((((((((((((((((((((((((((((((((((((((
  ... 5000 opening parens total, then 5000 closing parens ...)))))...)))))

(empty body)

The vulnerable code ran re.sub(r'\([^()]*\)', '', header) inside a while loop, repeating until no match was found. Each pass only removes innermost (non-nesting) paren pairs, so N levels of nesting requires N full-string regex passes. A 5,000-deep paren stack therefore triggers 5,000 sequential regex scans, each over a string that shrinks by only two characters per pass.

The patch (commit 746a69f) replaced the fix-point loop with a single linear scan: a character-by-character state machine (or equivalent stack-based approach) that identifies and removes comment spans in O(N) time, eliminating the quadratic blowup. This is a CWE-400 (Uncontrolled Resource Consumption) / CWE-1176 (Inefficient Regular Expression Complexity) issue.

The fix

Upgrade eml_parser to 3.0.2 or later (pip install --upgrade eml-parser). The fix is in commit 746a69f86443eb0b6a47f77db3cfe727c21f92b3 (PR #90), which replaces the quadratic fix-point regex loop with a linear-time CFWS comment stripper.

Reporter not attributed.

References: [1][2][3][4][5]

Related research