Aug 26, 2026·6 min read·2 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 critical logical flaw in the eml_parser Python module prior to version 3.0.2 allows malicious URLs to evade automated security analysis pipelines. By encoding key URI delimiter characters as HTML decimal entities, an attacker can mask indicators of compromise. Security controls, orchestration layers, and sandbox systems fail to detect these links, while downstream Mail User Agents natively reconstruct the malicious hyper-references when processed by end-users. This mechanism undermines the integrity of automated indicator extraction processes within Security Operations Centers.
Prior to version 3.0.2, GOVCERT-LU's eml_parser library is vulnerable to an algorithmic complexity Denial of Service (DoS) vulnerability via the comment-stripping routine noparenthesis() in routing.py. An unauthenticated attacker can submit a crafted EML file containing nested parenthesized comments to cause complete CPU saturation. This happens due to a quadratic time complexity bottleneck in regex replacement of nested structures.
Whistle prior to version 2.10.3 contains a path traversal vulnerability in its internal service layer. An unauthenticated remote attacker can read arbitrary files on the hosting operating system by issuing a crafted GET request containing relative or absolute file paths to the `/cgi-bin/temp/get` endpoint. This behavior occurs because the application fails open when an input file parameter does not match the temporary file format regex.
An arbitrary file read and write vulnerability exists in the Model Context Protocol (MCP) server endpoints of sublinear-time-solver and consciousness-explorer. By providing unvalidated file paths to the export_state, import_state, saveVectorToFile, and loadVectorFromFile tools, local attackers can read or overwrite sensitive host files.
An Authorization Bypass Through User-Controlled Key (CWE-639 / Insecure Direct Object Reference) vulnerability exists in @arikusi/deepseek-mcp-server starting in version 1.4.2 and fixed in 1.7.0. In Streamable HTTP transport mode, a process-global SessionStore singleton allows any remote client to retrieve or modify active conversation contexts belonging to other clients.
CVE-2026-45018 is a critical command injection vulnerability in Chainlit's Model Context Protocol (MCP) stdio transport backend. By submitting a crafted JSON payload containing dangerous argument options to an unauthenticated HTTP endpoint, a remote attacker can bypass executable validation rules and run arbitrary shell commands with the privileges of the active Python process.