Aug 26, 2026·6 min read·9 visits
An unhandled RecursionError in the address-parsing routines of eml_parser (< 3.0.2) allows unauthenticated remote attackers to crash email ingestion pipelines by submitting crafted email headers with deeply nested parentheses.
A denial of service vulnerability in GOVCERT-LU eml_parser before version 3.0.2 allows unauthenticated remote attackers to trigger an unhandled RecursionError exception. The issue arises during the parsing of structured email headers containing excessively nested parentheses representing Comments and Folding White Space (CFWS). Because the parser fails to catch this recursion-limit exception from Python's standard library, processing of the entire mail immediately aborts, which can disrupt automated security triage pipelines and email ingestion components.
The eml_parser is a widely utilized Python library designed to parse standard .eml files and extract structured metadata such as headers, attachments, and routing paths. Automated Security Operations Center (SOC) pipelines, mail exchange gateways, and threat intelligence ingestion systems heavily rely on this library to analyze untrusted emails.
The parser functions as a foundational component in automated security triage workflows. A denial of service vulnerability exists in versions of eml_parser prior to 3.0.2 due to how the library handles certain address-bearing headers. Specifically, the library delegates parsing of structured address fields to the Python standard library's email.utils module without wrapping the execution in safety-handling structures.
This exposure allows malformed payloads to impact the underlying interpreter. By transmitting an email with pathological headers that contain excessively nested comments, remote attackers can trigger an unhandled runtime exception. This exception terminates the execution thread of the importing program, stopping the entire ingestion process. As a result, entire analysis pipelines can be stalled by a single malicious message file.
The RFC 5322 specification governs the internet message format and permits the inclusion of Comments and Folding White Spaces (CFWS) inside address headers. These comments are denoted by opening and closing parentheses, and can legally be nested within one another.
This nested design presents a challenge for linear scanners, requiring parsing state engines to manage depth boundaries. The Python standard library email parser uses a recursive descent parsing algorithm to process address lists via email.utils.getaddresses(). Each nested parenthesis forces the parser to recurse one level deeper, allocating a new stack frame for each nesting level.
This implementation choice assumes that typical email formats will contain reasonably bounded structures. When the depth of nested parentheses exceeds Python's maximum recursion limit, which is typically set to 1000, the interpreter raises a RecursionError to prevent a stack overflow.
In vulnerable versions of eml_parser, the header_fetch_parse function fails to catch this error, causing the entire parsing execution to crash. Because there is no default exception handler in this specific processing path, the interpreter aborts immediately. Additionally, eml_parser employed an iterative regular expression matching strategy inside the internal utility function noparenthesis in eml_parser/routing.py. When encountering unmatched or complex parenthesized patterns, this regex execution exhibited quadratic ($O(N^2)$) time complexity, leading to excessive processor resource consumption.
The vulnerability was addressed in version 3.0.2 through two core modifications in the source code. The primary change wraps the vulnerable delegation call inside a try-except block to capture the stack exhaustion exception.
Below is the patch implemented within eml_parser/parser.py to intercept the unhandled recursion exception:
# Patched implementation in v3.0.2:
elif header in ('sender', 'resent-sender', 'to', 'resent-to', 'cc', 'resent-cc', 'bcc', 'resent-bcc', 'from', 'resent-from', 'reply-to'):
try:
return super().header_fetch_parse(name, value)
except RecursionError:
# Catch the standard library recursion limit exhaustion.
# Fall back to a regular expression extract to maintain partial functionality.
m = eml_parser.regexes.email_regex.findall(value)
return ', '.join(m)The second change involved replacing the inefficient recursive regex loop in noparenthesis with a linear-time stack-based array algorithm. This prevents performance degradation when processing dense sequences of parenthesis structures.
# Refactored stack-based parenthesis removal in eml_parser/routing.py
def noparenthesis(line: str) -> str:
fragments: list[list[str]] = [[]]
for ch in line:
if ch == '(':
fragments.append([ch])
else:
fragments[-1].append(ch)
if ch == ')' and len(fragments) > 1:
fragments.pop()
return ''.join(ch for w in fragments for ch in w)This linear algorithm ensures $O(N)$ execution time, neutralizing potential CPU exhaustion vectors.
Exploitation of this vulnerability is straightforward and requires no prior authentication or specialized network privileges. The attacker only needs to deliver a structured email payload containing a target header with several hundred open parentheses.
During testing, an address-bearing header such as From: containing 500 open parentheses followed by an email string successfully triggers the vulnerability. When the backend service attempts to run decode_email_bytes() on this input, the thread immediately aborts with an unhandled exception.
This attack vector can easily be integrated into standard email messages sent to target inboxes that feed directly into automated analysis scripts. Because many mail submission utilities do not filter comments dynamically, the pathological string passes through unchecked until parsed.
The concrete security impact is an application-level denial of service. For centralized mail servers or automatic SOC workflows processing hundreds of files per hour, an unhandled crash halts parsing pipelines and blocks administrative functions.
While the patch successfully prevents service crashes, the fallback extraction mechanism introduces a parser differential threat. When a RecursionError occurs, the parser falls back to matching raw emails via the generic regular expression email_regex instead of using the standard library's RFC 5322 engine.
This behavior means that upstream security gateways and downstream mail agents will interpret the sender and recipient fields differently. An attacker can craft a header that triggers fallback mode in the analysis tool, causing it to extract one address while the end-user's standard mail user agent (MUA) displays another address entirely.
Such inconsistencies undermine the integrity of downstream security controls. Automated systems may fail to align sender domains with SPF, DKIM, or DMARC validation records, allowing spoofed emails to bypass automated defensive boundaries.
Organizations utilizing the eml_parser library must immediately upgrade to version 3.0.2 or later to neutralize both the crash and performance bottlenecks. The patched library correctly processes pathological payloads without terminating execution.
If upgrading is not immediately possible, application developers must wrap all decode_email_bytes calls within custom exception handling blocks. Catching RecursionError and ValueError at the application level ensures that individual malicious files are quarantined without affecting the broader processing queue.
# Defensive wrapping template for legacy implementations
try:
parsed_data = ep.decode_email_bytes(raw_eml)
except (RecursionError, ValueError) as err:
syslog.syslog(syslog.LOG_ERR, f"Pathological email parsing aborted: {err}")
# Implement isolation or quarantine procedures hereAdditionally, boundary email transfer agents should be configured to drop or sanitize incoming mail headers that exhibit highly repetitive patterns of parentheses before they reach processing pipelines.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L| Product | Affected Versions | Fixed Version |
|---|---|---|
eml_parser GOVCERT-LU | < 3.0.2 | 3.0.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 / CWE-1124 |
| Attack Vector | Network |
| CVSS | 5.3 |
| Impact | Denial of Service |
| Exploit Status | PoC available |
| KEV Status | Not Listed |
The application allows deeply nested parsing structures leading to recursion depth exhaustion.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.
An elevation of privilege vulnerability exists in ASP.NET Core and Microsoft Visual Studio due to improper synchronization during concurrent thread execution. Authenticated remote attackers with low privileges can exploit a timing window to manipulate shared resources and assume higher-level execution contexts.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.