Sep 30, 2026·7 min read·4 visits
A parser logic flaw in Nodemailer allows attackers to inject secondary domains and spaces into email envelopes, leading to routing bypasses and email interception.
Nodemailer versions prior to 10.0.9 are vulnerable to a parser differential bug. When processing a quoted local-part followed by an RFC 5322 comment and trailing characters, the internal addressparser module fails to order its normalization routine correctly. This error results in the generation of malformed envelope recipient addresses containing injected whitespace and secondary domains, allowing attackers to bypass routing restrictions and exfiltrate sensitive emails.
The Nodemailer package is a widely adopted library within the Node.js ecosystem for sending emails via SMTP. The library abstracts transport-layer complexities, managing connection pooling, TLS handshakes, and RFC-compliant parsing of headers and email addresses. To handle recipient fields properly, Nodemailer relies on an internal parsing component known as the addressparser module, located in src/addressparser/index.ts.
The addressparser module is responsible for tokenizing and validating input address strings, transforming them into structured objects containing distinct 'name' and 'address' elements. This module must handle various RFC 5322 specifications, including quoted local-parts and comments. Because email addresses frequently contain arbitrary inputs, this parsing boundary represents a primary attack surface for input validation and routing control flaws.
Under GHSA-G57G-F23G-4646, a parser logic vulnerability exists in Nodemailer's address parsing routing. When processing a quoted local-part followed by an RFC 5322 comment and trailing non-comment text, the parser fails to reconstruct the tokens in the correct order. This failure allows an attacker to inject arbitrary characters, such as spaces and secondary domains, directly into the generated SMTP envelope recipient address, leading to potential routing control bypass or SMTP injection.
The root cause of GHSA-G57G-F23G-4646 is a parser differential order-of-operations bug combined with a tokenizer defect when handling quoted local-parts. Under the RFC 5322 standard, email addresses can include comments enclosed in parentheses, which are syntactically ignored during SMTP transmission. Additionally, local-parts can be enclosed in double quotes to allow whitespace and special characters that are otherwise restricted.
When the parser processes a quoted local-part, it handles the text path by storing the raw mailbox text inside a temporary array (data.text) instead of the final destination (data.address). To remove comments or extraneous display names, the parser invokes an internal helper function called _recoverAddrSpec(data). In the vulnerable implementation, this function was executed before the quotes were restored back onto the local-part via _quoteLocalPart(data).
Because the local-part was evaluated in its unquoted state, the recovery logic in _recoverAddrSpec(data) could not differentiate between legitimate whitespace inside a quoted string and trailing metadata left behind after comment stripping. This confusion caused the parser to merge the trailing payload into the final address-spec. Furthermore, empty quoted strings ("") were dropped entirely by the tokenizer, leaving no text token to record that the string was originally quoted, which led to incorrect stripping of domain markers.
The logic error resides in the _handleAddress function within src/addressparser/index.ts. In the vulnerable code path, the address structure is evaluated first, and the quoting logic is applied as a post-processing step on the finalized address structure. This order of execution prevents the parser from preserving state information when processing RFC 5322 comments.
// VULNERABLE CODE PATH FLOW
_recoverAddrSpec(data);
if (addressFromQuotedText && address.address) {
address.address = _quoteLocalPart(address.address);
}In this vulnerable flow, if an input of '"user"@good-corp.com(x)evil.com' is parsed, the parser extracts 'user' as the local-part, but when resolving the address specification, it fails to separate 'evil.com' because the quotes are not yet present on the local-part. This results in the address 'user@good-corp.com evil.com' being generated.
The patch modifies this flow by applying the quoting function immediately if addressFromQuotedText is true, ensuring that the address specification recovery helper operates on a fully quoted and normalized local-part. This allows the parser to identify the whitespace and correctly separate the secondary domain into the display name field.
// PATCHED CODE PATH FLOW
if (addressFromQuotedText && data.text) {
// Put quotes back on first so recovery can tell whitespace from wreckage
data.address = _quoteLocalPart(data.text);
data.text = '';
}
_recoverAddrSpec(data);Additionally, the patch resolves the empty quoted string flaw by checking if the previous tokens represent a double-quote sequence (""). This sets the opensAfterEmptyQuotedString variable, ensuring that the quoting context is properly maintained even if the tokenizer yields no token for the empty string itself.
An attack utilizing GHSA-G57G-F23G-4646 requires the target application to accept user-provided email addresses, perform domain validation, and subsequently pass the validated address to Nodemailer. The exploitation flow targets the differential between the application's strict validator and Nodemailer's vulnerable parser.
First, the attacker registers or submits an input containing a payload such as "user"@good-corp.com(x)evil.com. A standard, RFC-compliant email validator in the application parser processes this input according to correct specifications, resolving the destination domain as good-corp.com (ignoring the comment and wreckage) and approving the input because it matches an authorized domain whitelist.
Second, the approved address is passed directly to Nodemailer. Due to the parser differential, Nodemailer's addressparser fails to discard the trailing text and constructs the following malformed SMTP command:
RCPT TO:<user@good-corp.com evil.com>
Depending on the downstream Mail Transfer Agent (MTA) or SMTP server, the injected whitespace can result in two outcomes. In the first outcome, the MTA splits the recipient parameters on the space character, generating two delivery targets and routing a copy of the email to evil.com. In the second outcome, the MTA's parser reads the last domain as the active routing target, delivering the entire email directly to the attacker-controlled server at evil.com.
The primary impact of GHSA-G57G-F23G-4646 is a severe compromise of email routing security, leading to information disclosure and authentication bypass. In modern web architectures, automated transactional emails—such as password reset tokens, multi-factor authentication (MFA) codes, and financial invoices—are frequently routed to users based on database or application-level rules. If an attacker can manipulate the recipient envelope via parser differentials, they can intercept these communications.
Consider an enterprise application that restricts notifications to internal employees via domain-level whitelisting (e.g., @good-corp.com). By exploiting this vulnerability, an external actor can bypass the whitelist and force the SMTP server to route copies of internal emails to an external mailbox. This allows unauthenticated actors to retrieve password reset links or session tokens, resulting in privilege escalation.
Furthermore, the injection of whitespace in SMTP headers introduces risk of SMTP parameter injection. Attackers can leverage the space character to append additional SMTP verbs or parameters (such as delivery status notifications or custom routing flags) to the RCPT TO envelope command. This can lead to auxiliary diagnostic exploits or service disruptions on the hosting mail server.
The recommended remediation for GHSA-G57G-F23G-4646 is to upgrade Nodemailer to version 10.0.9 or higher. This version corrects the order of operations within the address parser, guaranteeing that quoted local-parts are fully reconstructed before comment-handling logic executes. Downstream packages must update their dependency trees immediately.
If upgrading Nodemailer is not immediately feasible due to legacy system constraints, teams must implement defensive input validation filters upstream. Applications should deploy a strict sanitization step that rejects any input addresses containing double-quote pairs ("") or parentheses ((, )) before passing them to the mail utility.
// Temporary upstream validation workaround
function isSafeEmail(email) {
// Reject common characters used in RFC 5322 parser exploits
const dangerousPatterns = /[()"]/;
return !dangerousPatterns.test(email);
}Additionally, security teams should configure downstream Mail Transfer Agents (MTAs) to strictly reject any RCPT TO command that contains spaces or invalid syntax. Restricting the MTA parser's tolerance for non-standard envelope structures serves as a robust defense-in-depth measure against injection attempts.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
nodemailer Nodemailer | < 10.0.9 | 10.0.9 |
| Attribute | Detail |
|---|---|
| Vulnerability Type | Parser Differential / SMTP Parameter Injection |
| CWE ID | CWE-20 |
| Attack Vector | Network / Input-driven |
| Affected Component | src/addressparser/index.ts |
| Exploit Status | Proof of Concept |
| Remediation Status | Official Patch Available (v10.0.9) |
Improper Input Validation
A Regular Expression Denial of Service (ReDoS) vulnerability exists in Nodemailer's addressparser fallback engine before version 10.0.6. Under specific malformed inputs with excessive word boundaries, the parser exhibits quadratic backtracking, leading to high CPU utilization and event loop blockage.
CVE-2026-102276 is a high-severity Denial of Service (DoS) vulnerability impacting the 'brace-expansion' library, a popular Node.js utility designed to expand brace patterns into combinatorial lists. Due to uncontrolled recursion and argument-list stack exhaustion within the internal parseCommaParts function, remote attackers can trigger an unhandled RangeError that abruptly terminates the Node.js process.
A stack-based Denial of Service (DoS) vulnerability via uncontrolled recursion in the brace-expansion library prior to versions 1.1.20, 2.1.6, 3.0.8, and 5.0.11 allows unauthenticated remote attackers to trigger native stack exhaustion, terminating the Node.js process via a crafted payload containing deeply nested brace groups.
An uncontrolled resource consumption vulnerability exists in the brace-expansion JavaScript library. Due to an algorithmic flaw in parsing a legacy Bash-compatibility quirk involving {a},b}-shaped expansion structures, untrusted inputs containing many trailing closing braces trigger successive full-input rescans. This behavior yields quadratic CPU time complexity and high memory overhead, allowing remote, unauthenticated attackers to cause a Denial of Service (DoS) by blocking the single-threaded Node.js event loop.
Moment.js versions 2.29.2 through 2.30.1 are vulnerable to a Path Traversal flaw (CWE-27) on server-side Node.js environments when dynamic locales are configured. The vulnerability stems from an object-coercion bypass in the locale-name sanitization routine, which assumes incoming variables are string primitives. An attacker can pass a structured object with custom 'match' and 'toString' properties to bypass regex-based directory checks, leading to arbitrary file loading via Node's internal 'require()' call.
A denial-of-service vulnerability exists in the ip-address npm package prior to version 10.7.1. The library fails to limit the length of input strings parsed by the Address4 and Address6 constructors. When parsing highly malformed addresses, the diagnostic parser runs a synchronous regular expression search-and-replace that generates descriptive HTML error messages. Passing an excessively long string containing invalid characters causes severe memory amplification and CPU starvation, resulting in a thread hang or process crash in Node.js applications.