CVE-2026-110872
Nodemailer 3.0.0 before 10.0.10 Denial of Service via SMTP Reply Parsing
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- High
Exploit likelihood
What each source reports
CVE List Score used
8.2
Nodemailer 3.0.0 before 10.0.10 Denial of Service via SMTP Reply Parsing
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
CVE-2026-110872- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
EUVDEUVD-2026-101755
8.2
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
EUVD-2026-101755- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-37fc-hcrp-mmff
8.2
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service...
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
GHSA-37fc-hcrp-mmff- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4g23-2xm8-66gc
5.9
Nodemailer: Quadratic (O(n^2)) SMTP client reply parsing lets a malicious server or MITM cause a pre-auth remote denial of service
Summary
The SMTP client response parser reassembles multiline server replies by appending each continuation line onto a single response-queue entry and re-testing whether that entry is still a partial (continuation) reply on every line. The partial-response test runs str.slice(str.lastIndexOf('\n') + 1) on the growing entry, which forces a full flatten of the entire accumulated string on each line. A malicious or compromised SMTP server (or an on-path attacker on a plaintext or pre-STARTTLS hop) that streams continuation lines and never sends a completion line drives O(n^2) CPU on the single-threaded Node.js event loop before any authentication, freezing the whole process for an attacker-controlled duration.
Root Cause
The invariant that a server cannot cause superlinear client-side work while a reply is being reassembled is violated. In src/smtp-connection/index.ts, _onData splits inbound bytes into lines and, while the last queued entry is a continuation reply, concatenates each new line onto that same entry with this._responseQueue[len - 1] += '\n' + lines[i]. On every iteration it calls isPartialResponse(lastline), which evaluates /^\d+-/.test(str.slice(str.lastIndexOf('\n') + 1)). Because the queued entry grows by one line per continuation line and is stored as a V8 rope (ConsString), each lastIndexOf/slice forces a full string flatten of length proportional to the accumulated reply. Executed once per line over n continuation lines, this is O(n^2) CPU. While the reply stays partial the function early-returns and never resets the entry, so the growth and the per-line reflatten continue unbounded. There is no response-size or line-count cap in the connection code; the only limits are time-based (greetingTimeout, and an inactivity socketTimeout), and neither bounds accumulated reply size.
Affected file and functions (verified at the published v10.0.9 artifact, in src/ and in the built dist/cjs and dist/esm output):
- src/smtp-connection/index.ts: isPartialResponse (the /^\d+-/ test over str.slice(str.lastIndexOf('\n')+1))
- src/smtp-connection/index.ts: SMTPConnection._onData (the continuation-line append loop with no size cap)
Impact
An attacker who is, or can impersonate, the SMTP peer the client connects to can freeze the connecting Node.js process. Because Node.js is single-threaded, event-loop starvation halts all other work in that process (every other connection, request, and timer), not just the offending SMTP session. The reply is parsed during the greeting and EHLO phases, before the client authenticates or issues any command, so no credentials on the client are required. The blocking duration scales with the volume of continuation data the attacker streams and can be sustained indefinitely by continuing to stream, and memory for the accumulated entry also grows without bound. Independent reproduction on Node.js 24 measured roughly 11.6 seconds of event-loop blocking for about 640 KB of continuation data and roughly 47 seconds for about 1.3 MB, scaling quadratically. This is a repeatable remote denial of service against the sending process.
Proof of Concept
Node.js 24; a raw TCP listener acting as a hostile SMTP server; the client uses the shipped SMTPConnection (require('nodemailer/lib/smtp-connection')).
Steps: (1) start a TCP server that accepts a connection and streams continuation lines of the form 220-flood...\r\n in large batches, never emitting a completion line such as 220 ready; (2) point an SMTPConnection at it and observe the client event loop stall while the single response-queue entry grows and is reflattened on every line. A minimal microbenchmark of the exact parsing logic demonstrates the complexity:
// Reproduces isPartialResponse + the _onData append loop verbatim (Node 24).
function isPartialResponse(str) { return /^\d+-/.test(str.slice(str.lastIndexOf('\n') + 1)); }
function run(n) {
const queue = [];
let remainder = '';…
- Record
GHSA-4g23-2xm8-66gc- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-85x2-q946-cp5h
6.5
Nodemailer: A ">" inside a quoted local part ends an angle-addr early in addressparser, delivering to a domain the header does not name
Vulnerability summary
addressparser ends an angle-addr at the first > it sees, including one inside a quoted local part, a comment or a domain literal. The domain is then read off the text in front of that >. <"[email protected]>"@good.com> is the mailbox "[email protected]>"@good.com under RFC 5322, and Nodemailer read it as an address at evil.com. The unbracketed spelling of the same value was already read correctly. Affected: 3.0.0 through 10.1.3.
Attacker capabilities
The attacker controls the text of a recipient or sender address that an application passes to Nodemailer, for example a To value entered in a contact or invite form, or the header of an inbound message parsed with mailparser. No access to the application, its configuration or its credentials is needed. The value is a syntactically valid RFC 5322 address that conformant parsers accept without defects.
Realistic exploitation scenario
An application lets users send invitations or notifications only to addresses at an allowed domain and validates the submitted value with a conformant parser or by checking its domain. The attacker submits <"[email protected]>"@good.com>, which validates as a good.com mailbox. Nodemailer then parses the same value, issues RCPT TO:<"\"a"@evil.com> and the message, with whatever content the application puts into it, is delivered to the attacker's domain. The security boundary crossed is the application's recipient allow list. In the inbound direction, mailparser reports a different address than a conformant reader of the same header, so a display or policy layer built on the two disagrees.
Proof of concept
const addressparser = require('nodemailer/lib/addressparser');
console.log(addressparser("<\"[email protected]>\"@good.com>"));
// [ { address: '"[email protected]', name: '@good.com>' } ]
Python's email._header_value_parser.get_address_list reads the same value as "[email protected]>"@good.com, with no defects reported.
The envelope a message gets is built from the same parse, so sendMail({ to: "<\"[email protected]>\"@good.com>" }) issues the RCPT TO shown above.
Security impact
Mail that an application intends for an allowed domain is delivered to a domain chosen by the attacker, which discloses its content. It is a security vulnerability rather than a parsing bug because the misreading only occurs for values that a conformant validator approves, so validation done the right way is bypassed. Affected are applications that pass user influenced addresses to Nodemailer and consumers of the standalone parser such as mailparser.
The fix tracks quoted strings, comments and domain literals inside an angle-addr and reads only a > outside them.
Found in an internal review of addressparser on 2026-10-18. Verified on 3.0.0, 6.9.16 and 10.1.3.
- Record
GHSA-85x2-q946-cp5h- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
GitHub AdvisoriesGHSA-8c8m-p3m8-cjg8
6.5
Nodemailer: A nested comment ends early in addressparser, releasing the rest of the comment as a recipient
Vulnerability summary
RFC 5322 comments nest. addressparser ended a comment at the first ), including the one that closes a nested comment, and parsed the rest of the outer comment as header text. Victim (x(y) <[email protected]>) <[email protected]> names [email protected] with x(y) <[email protected]> as a comment, and Nodemailer read it as the address [email protected]. This is the same shape as the escaped parenthesis fixed in 10.1.2, reached through nesting instead of a quoted-pair. Affected: 3.0.0 through 10.1.3.
Attacker capabilities
The attacker controls the text of an address that an application passes to Nodemailer, or the From or To header of an inbound message parsed with mailparser. No access to the application, its configuration or its credentials is needed. The value is a syntactically valid RFC 5322 address that conformant parsers accept without defects.
Realistic exploitation scenario
An application validates a submitted address with a conformant parser and allows only its own domain. The attacker submits Victim (x(y) <[email protected]>) <[email protected]>, which validates as [email protected]. Nodemailer delivers to [email protected]. In the inbound direction, a DMARC or display layer built on a conformant parser and a mail client built on mailparser disagree on the author of the same message, which is the setting for sender spoofing. The boundary crossed is the application's recipient allow list, or the author check of the receiving side.
Proof of concept
const addressparser = require('nodemailer/lib/addressparser');
console.log(addressparser("Victim (x(y) <[email protected]>) <[email protected]>"));
// [ { address: '[email protected]', name: 'Victim) [email protected]' } ]
Python's email._header_value_parser.get_address_list reads the same value as [email protected] with the display name Victim, with no defects reported.
The envelope a message gets is built from the same parse, so sendMail({ to: "Victim (x(y) <[email protected]>) <[email protected]>" }) issues the RCPT TO shown above.
Security impact
Mail intended for an approved recipient is delivered to an attacker chosen domain, disclosing its content, and parsers built on this module report a different author than conformant ones. The misreading only occurs on values a conformant validator approves, so correct validation is bypassed. Affected are applications that pass user influenced addresses to Nodemailer and consumers of the standalone parser such as mailparser.
The fix counts comment depth and ends a comment only at the ) that closes the outermost one.
Found in an internal review of addressparser on 2026-10-18. Verified on 3.0.0, 6.9.16 and 10.1.3.
- Record
GHSA-8c8m-p3m8-cjg8- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
Show 28 moreShow less
GitHub AdvisoriesGHSA-m943-m63m-w62w
6.5
Nodemailer: A ";" inside a quoted string or comment ends an address group early in addressparser, turning display text into a recipient
Vulnerability summary
addressparser ends an RFC 5322 group at the first ;, including one inside a quoted display name or a comment. The text after it is parsed again as top level recipients with the quoting flipped, so text that every conformant parser reads as a display name or comment becomes a live address. G: (a; <[email protected]>) <[email protected]>; names only [email protected], and Nodemailer read it as the single recipient [email protected]. Affected: 3.0.0 through 10.1.3.
Attacker capabilities
The attacker controls the text of an address field that an application passes to Nodemailer, or the header of an inbound message parsed with mailparser. No access to the application, its configuration or its credentials is needed. The value is a syntactically valid RFC 5322 group that conformant parsers accept without defects.
Realistic exploitation scenario
An application validates the recipients of a submitted address list with a conformant parser and only allows addresses at its own domain. The attacker submits G: (a; <[email protected]>) <[email protected]>;. The validator sees one mailbox, [email protected], and approves it. Nodemailer delivers to [email protected] only. The same works through a quoted display name, G: "a;" "<[email protected]>" <[email protected]>;. The boundary crossed is the application's recipient allow list.
Proof of concept
const addressparser = require('nodemailer/lib/addressparser');
console.log(addressparser("G: (a; <[email protected]>) <[email protected]>;"));
// [ { name: 'G', group: [ [Object] ] }, { address: '[email protected]', name: ') [email protected]' } ]
Python's email._header_value_parser.get_address_list reads the same value as the single mailbox [email protected], with no defects reported.
The envelope a message gets is built from the same parse, so sendMail({ to: "G: (a; <[email protected]>) <[email protected]>;" }) issues the RCPT TO shown above.
Security impact
Mail that an application intends for an approved recipient goes to a recipient chosen by the attacker, which discloses its content, and the intended recipient never receives it. The misreading only occurs on values a conformant validator approves, so correct validation is bypassed, which makes it a security issue rather than a parsing bug. Affected are applications that pass user influenced address lists to Nodemailer and consumers of the standalone parser such as mailparser.
The fix tracks quoted strings and comments inside a group and reads only a ; outside them.
Found in an internal review of addressparser on 2026-10-18. Verified on 3.0.0, 6.9.16 and 10.1.3.
- Record
GHSA-m943-m63m-w62w- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-02
NVD
8.2
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
CVE-2026-110872- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400
- Updated
- 2026-11-02
OSV
8.2
Nodemailer 3.0.0 before 10.0.10 Denial of Service via SMTP Reply Parsing
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
CVE-2026-110872- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - Weakness
- CWE-400
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-110872
8.2
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
DEBIAN-CVE-2026-110872- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - Updated
- 2026-11-02
OSVGHSA-4g23-2xm8-66gc
5.9
Nodemailer: Quadratic (O(n^2)) SMTP client reply parsing lets a malicious server or MITM cause a pre-auth remote denial of service
Summary
The SMTP client response parser reassembles multiline server replies by appending each continuation line onto a single response-queue entry and re-testing whether that entry is still a partial (continuation) reply on every line. The partial-response test runs str.slice(str.lastIndexOf('\n') + 1) on the growing entry, which forces a full flatten of the entire accumulated string on each line. A malicious or compromised SMTP server (or an on-path attacker on a plaintext or pre-STARTTLS hop) that streams continuation lines and never sends a completion line drives O(n^2) CPU on the single-threaded Node.js event loop before any authentication, freezing the whole process for an attacker-controlled duration.
Root Cause
The invariant that a server cannot cause superlinear client-side work while a reply is being reassembled is violated. In src/smtp-connection/index.ts, _onData splits inbound bytes into lines and, while the last queued entry is a continuation reply, concatenates each new line onto that same entry with this._responseQueue[len - 1] += '\n' + lines[i]. On every iteration it calls isPartialResponse(lastline), which evaluates /^\d+-/.test(str.slice(str.lastIndexOf('\n') + 1)). Because the queued entry grows by one line per continuation line and is stored as a V8 rope (ConsString), each lastIndexOf/slice forces a full string flatten of length proportional to the accumulated reply. Executed once per line over n continuation lines, this is O(n^2) CPU. While the reply stays partial the function early-returns and never resets the entry, so the growth and the per-line reflatten continue unbounded. There is no response-size or line-count cap in the connection code; the only limits are time-based (greetingTimeout, and an inactivity socketTimeout), and neither bounds accumulated reply size.
Affected file and functions (verified at the published v10.0.9 artifact, in src/ and in the built dist/cjs and dist/esm output):
- src/smtp-connection/index.ts: isPartialResponse (the /^\d+-/ test over str.slice(str.lastIndexOf('\n')+1))
- src/smtp-connection/index.ts: SMTPConnection._onData (the continuation-line append loop with no size cap)
Impact
An attacker who is, or can impersonate, the SMTP peer the client connects to can freeze the connecting Node.js process. Because Node.js is single-threaded, event-loop starvation halts all other work in that process (every other connection, request, and timer), not just the offending SMTP session. The reply is parsed during the greeting and EHLO phases, before the client authenticates or issues any command, so no credentials on the client are required. The blocking duration scales with the volume of continuation data the attacker streams and can be sustained indefinitely by continuing to stream, and memory for the accumulated entry also grows without bound. Independent reproduction on Node.js 24 measured roughly 11.6 seconds of event-loop blocking for about 640 KB of continuation data and roughly 47 seconds for about 1.3 MB, scaling quadratically. This is a repeatable remote denial of service against the sending process.
Proof of Concept
Node.js 24; a raw TCP listener acting as a hostile SMTP server; the client uses the shipped SMTPConnection (require('nodemailer/lib/smtp-connection')).
Steps: (1) start a TCP server that accepts a connection and streams continuation lines of the form 220-flood...\r\n in large batches, never emitting a completion line such as 220 ready; (2) point an SMTPConnection at it and observe the client event loop stall while the single response-queue entry grows and is reflattened on every line. A minimal microbenchmark of the exact parsing logic demonstrates the complexity:
// Reproduces isPartialResponse + the _onData append loop verbatim (Node 24).
function isPartialResponse(str) { return /^\d+-/.test(str.slice(str.lastIndexOf('\n') + 1)); }
function run(n) {
const queue = [];
let remainder = '';…
- Record
GHSA-4g23-2xm8-66gc- CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - Weakness
- CWE-400, CWE-407
- Updated
- 2026-11-02
OSVGHSA-85x2-q946-cp5h
6.5
Nodemailer: A ">" inside a quoted local part ends an angle-addr early in addressparser, delivering to a domain the header does not name
Vulnerability summary
addressparser ends an angle-addr at the first > it sees, including one inside a quoted local part, a comment or a domain literal. The domain is then read off the text in front of that >. <"[email protected]>"@good.com> is the mailbox "[email protected]>"@good.com under RFC 5322, and Nodemailer read it as an address at evil.com. The unbracketed spelling of the same value was already read correctly. Affected: 3.0.0 through 10.1.3.
Attacker capabilities
The attacker controls the text of a recipient or sender address that an application passes to Nodemailer, for example a To value entered in a contact or invite form, or the header of an inbound message parsed with mailparser. No access to the application, its configuration or its credentials is needed. The value is a syntactically valid RFC 5322 address that conformant parsers accept without defects.
Realistic exploitation scenario
An application lets users send invitations or notifications only to addresses at an allowed domain and validates the submitted value with a conformant parser or by checking its domain. The attacker submits <"[email protected]>"@good.com>, which validates as a good.com mailbox. Nodemailer then parses the same value, issues RCPT TO:<"\"a"@evil.com> and the message, with whatever content the application puts into it, is delivered to the attacker's domain. The security boundary crossed is the application's recipient allow list. In the inbound direction, mailparser reports a different address than a conformant reader of the same header, so a display or policy layer built on the two disagrees.
Proof of concept
const addressparser = require('nodemailer/lib/addressparser');
console.log(addressparser("<\"[email protected]>\"@good.com>"));
// [ { address: '"[email protected]', name: '@good.com>' } ]
Python's email._header_value_parser.get_address_list reads the same value as "[email protected]>"@good.com, with no defects reported.
The envelope a message gets is built from the same parse, so sendMail({ to: "<\"[email protected]>\"@good.com>" }) issues the RCPT TO shown above.
Security impact
Mail that an application intends for an allowed domain is delivered to a domain chosen by the attacker, which discloses its content. It is a security vulnerability rather than a parsing bug because the misreading only occurs for values that a conformant validator approves, so validation done the right way is bypassed. Affected are applications that pass user influenced addresses to Nodemailer and consumers of the standalone parser such as mailparser.
The fix tracks quoted strings, comments and domain literals inside an angle-addr and reads only a > outside them.
Found in an internal review of addressparser on 2026-10-18. Verified on 3.0.0, 6.9.16 and 10.1.3.
- Record
GHSA-85x2-q946-cp5h- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-04
OSVGHSA-8c8m-p3m8-cjg8
6.5
Nodemailer: A nested comment ends early in addressparser, releasing the rest of the comment as a recipient
Vulnerability summary
RFC 5322 comments nest. addressparser ended a comment at the first ), including the one that closes a nested comment, and parsed the rest of the outer comment as header text. Victim (x(y) <[email protected]>) <[email protected]> names [email protected] with x(y) <[email protected]> as a comment, and Nodemailer read it as the address [email protected]. This is the same shape as the escaped parenthesis fixed in 10.1.2, reached through nesting instead of a quoted-pair. Affected: 3.0.0 through 10.1.3.
Attacker capabilities
The attacker controls the text of an address that an application passes to Nodemailer, or the From or To header of an inbound message parsed with mailparser. No access to the application, its configuration or its credentials is needed. The value is a syntactically valid RFC 5322 address that conformant parsers accept without defects.
Realistic exploitation scenario
An application validates a submitted address with a conformant parser and allows only its own domain. The attacker submits Victim (x(y) <[email protected]>) <[email protected]>, which validates as [email protected]. Nodemailer delivers to [email protected]. In the inbound direction, a DMARC or display layer built on a conformant parser and a mail client built on mailparser disagree on the author of the same message, which is the setting for sender spoofing. The boundary crossed is the application's recipient allow list, or the author check of the receiving side.
Proof of concept
const addressparser = require('nodemailer/lib/addressparser');
console.log(addressparser("Victim (x(y) <[email protected]>) <[email protected]>"));
// [ { address: '[email protected]', name: 'Victim) [email protected]' } ]
Python's email._header_value_parser.get_address_list reads the same value as [email protected] with the display name Victim, with no defects reported.
The envelope a message gets is built from the same parse, so sendMail({ to: "Victim (x(y) <[email protected]>) <[email protected]>" }) issues the RCPT TO shown above.
Security impact
Mail intended for an approved recipient is delivered to an attacker chosen domain, disclosing its content, and parsers built on this module report a different author than conformant ones. The misreading only occurs on values a conformant validator approves, so correct validation is bypassed. Affected are applications that pass user influenced addresses to Nodemailer and consumers of the standalone parser such as mailparser.
The fix counts comment depth and ends a comment only at the ) that closes the outermost one.
Found in an internal review of addressparser on 2026-10-18. Verified on 3.0.0, 6.9.16 and 10.1.3.
- Record
GHSA-8c8m-p3m8-cjg8- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-04
OSVGHSA-m943-m63m-w62w
6.5
Nodemailer: A ";" inside a quoted string or comment ends an address group early in addressparser, turning display text into a recipient
Vulnerability summary
addressparser ends an RFC 5322 group at the first ;, including one inside a quoted display name or a comment. The text after it is parsed again as top level recipients with the quoting flipped, so text that every conformant parser reads as a display name or comment becomes a live address. G: (a; <[email protected]>) <[email protected]>; names only [email protected], and Nodemailer read it as the single recipient [email protected]. Affected: 3.0.0 through 10.1.3.
Attacker capabilities
The attacker controls the text of an address field that an application passes to Nodemailer, or the header of an inbound message parsed with mailparser. No access to the application, its configuration or its credentials is needed. The value is a syntactically valid RFC 5322 group that conformant parsers accept without defects.
Realistic exploitation scenario
An application validates the recipients of a submitted address list with a conformant parser and only allows addresses at its own domain. The attacker submits G: (a; <[email protected]>) <[email protected]>;. The validator sees one mailbox, [email protected], and approves it. Nodemailer delivers to [email protected] only. The same works through a quoted display name, G: "a;" "<[email protected]>" <[email protected]>;. The boundary crossed is the application's recipient allow list.
Proof of concept
const addressparser = require('nodemailer/lib/addressparser');
console.log(addressparser("G: (a; <[email protected]>) <[email protected]>;"));
// [ { name: 'G', group: [ [Object] ] }, { address: '[email protected]', name: ') [email protected]' } ]
Python's email._header_value_parser.get_address_list reads the same value as the single mailbox [email protected], with no defects reported.
The envelope a message gets is built from the same parse, so sendMail({ to: "G: (a; <[email protected]>) <[email protected]>;" }) issues the RCPT TO shown above.
Security impact
Mail that an application intends for an approved recipient goes to a recipient chosen by the attacker, which discloses its content, and the intended recipient never receives it. The misreading only occurs on values a conformant validator approves, so correct validation is bypassed, which makes it a security issue rather than a parsing bug. Affected are applications that pass user influenced address lists to Nodemailer and consumers of the standalone parser such as mailparser.
The fix tracks quoted strings and comments inside a group and reads only a ; outside them.
Found in an internal review of addressparser on 2026-10-18. Verified on 3.0.0, 6.9.16 and 10.1.3.
- Record
GHSA-m943-m63m-w62w- CVSS 3.1
- 6.5 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:L/A:N - Weakness
- CWE-20, CWE-436
- Updated
- 2026-11-04
OSVUBUNTU-CVE-2026-110872
8.2
Nodemailer from 3.0.0 before 10.0.10 contains a quadratic complexity denial of service vulnerability in the SMTP client reply parser in SMTPConnection._onData and isPartialResponse. A malicious SMTP server or on-path attacker can stream continuation lines without a completion line before authentication, blocking the Node.js event loop and exhausting memory.
- Record
UBUNTU-CVE-2026-110872- CVSS 4.0
- 8.2 High
CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N - CVSS 3.1
- 5.9 Medium
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H - Updated
- 2026-11-02
OSVCLSA-2026-1792445608 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.6-tuxcare.3.
- Record
CLSA-2026-1792445608- Updated
- 2026-11-02
OSVCLSA-2026-1792473237 No score
TuxCare security update for nodemailer (3 CVEs)
TuxCare rebuilt nodemailer to address 3 CVEs. Fixed in 9.1.0-tuxcare.6.
- Record
CLSA-2026-1792473237- Updated
- 2026-11-02
OSVCLSA-2026-1792476053 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.5-tuxcare.4.
- Record
CLSA-2026-1792476053- Updated
- 2026-11-02
OSVCLSA-2026-1792486145 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.3-tuxcare.4.
- Record
CLSA-2026-1792486145- Updated
- 2026-11-02
OSVCLSA-2026-1792496101 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.2-tuxcare.4.
- Record
CLSA-2026-1792496101- Updated
- 2026-11-02
OSVCLSA-2026-1793102000 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.2-tuxcare.6.
- Record
CLSA-2026-1793102000- Updated
- 2026-11-02
OSVCLSA-2026-1793102100 No score
TuxCare security update for nodemailer (1 CVE)
TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 9.0.6-tuxcare.5.
- Record
CLSA-2026-1793102100- Updated
- 2026-11-02
OSVCLSA-2026-1793102196 No score
TuxCare security update for nodemailer (3 CVEs)
TuxCare rebuilt nodemailer to address 3 CVEs. Fixed in 9.1.0-tuxcare.7.
- Record
CLSA-2026-1793102196- Updated
- 2026-11-02
OSVCLSA-2026-1793102303 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.5-tuxcare.6.
- Record
CLSA-2026-1793102303- Updated
- 2026-11-02
OSVCLSA-2026-1793102402 No score
TuxCare security update for nodemailer (3 CVEs)
TuxCare rebuilt nodemailer to address 3 CVEs. Fixed in 9.0.0-tuxcare.6.
- Record
CLSA-2026-1793102402- Updated
- 2026-11-02
OSVCLSA-2026-1793102503 No score
TuxCare security update for nodemailer (3 CVEs)
TuxCare rebuilt nodemailer to address 3 CVEs. Fixed in 9.0.3-tuxcare.6.
- Record
CLSA-2026-1793102503- Updated
- 2026-11-02
OSVCLSA-2026-1793102593 No score
TuxCare security update for nodemailer (4 CVEs)
TuxCare rebuilt nodemailer to address 4 CVEs. Fixed in 9.0.1-tuxcare.5.
- Record
CLSA-2026-1793102593- Updated
- 2026-11-02
OSVCLSA-2026-1793102824 No score
TuxCare security update for nodemailer (3 CVEs)
TuxCare rebuilt nodemailer to address 3 CVEs. Fixed in 6.10.1-tuxcare.15.
- Record
CLSA-2026-1793102824- Updated
- 2026-11-02
OSVCLSA-2026-1793109577 No score
TuxCare security update for nodemailer (1 CVE)
TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 9.0.5-tuxcare.7.
- Record
CLSA-2026-1793109577- Updated
- 2026-11-02
OSVCLSA-2026-1793109690 No score
TuxCare security update for nodemailer (1 CVE)
TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 9.0.2-tuxcare.7.
- Record
CLSA-2026-1793109690- Updated
- 2026-11-02
OSVCLSA-2026-1793109772 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.6-tuxcare.6.
- Record
CLSA-2026-1793109772- Updated
- 2026-11-02
OSVCLSA-2026-1793181005 No score
TuxCare security update for nodemailer (1 CVE)
TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 9.0.0-tuxcare.7.
- Record
CLSA-2026-1793181005- Updated
- 2026-11-02
OSVCLSA-2026-1793183896 No score
TuxCare security update for nodemailer (1 CVE)
TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 6.10.1-tuxcare.16.
- Record
CLSA-2026-1793183896- Updated
- 2026-11-02
OSVCLSA-2026-1793790053 No score
TuxCare security update for nodemailer (2 CVEs)
TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 2.7.2-tuxcare.10.
- Record
CLSA-2026-1793790053- Updated
- 2026-11-04
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
nodemailernpm |
3.0.0 to 10.0.9 | 10.0.10 |
nodemailernpm |
3.0.0 up to 10.1.4 | 10.1.4 |
nodemailerTuxCare:npm From an advisory covering 2 CVEs |
9.0.6-tuxcare.0 up to 9.0.6-tuxcare.3, plus listed versions 9.0.69.0.6-tuxcare.19.0.6-tuxcare.2 |
9.0.6-tuxcare.3 |
nodemailerTuxCare:npm From an advisory covering 3 CVEs |
9.1.0-tuxcare.0 up to 9.1.0-tuxcare.6, plus listed versions 9.1.09.1.0-tuxcare.19.1.0-tuxcare.29.1.0-tuxcare.39.1.0-tuxcare.49.1.0-tuxcare.5 |
9.1.0-tuxcare.6 |
nodemailerTuxCare:npm From an advisory covering 2 CVEs |
9.0.5-tuxcare.0 up to 9.0.5-tuxcare.4, plus listed versions 9.0.59.0.5-tuxcare.19.0.5-tuxcare.29.0.5-tuxcare.3 |
9.0.5-tuxcare.4 |
nodemailerTuxCare:npm From an advisory covering 2 CVEs |
9.0.3-tuxcare.0 up to 9.0.3-tuxcare.4, plus listed versions 9.0.39.0.3-tuxcare.19.0.3-tuxcare.29.0.3-tuxcare.3 |
9.0.3-tuxcare.4 |
nodemailerTuxCare:npm From an advisory covering 2 CVEs |
9.0.2-tuxcare.0 up to 9.0.2-tuxcare.4, plus listed versions 9.0.29.0.2-tuxcare.19.0.2-tuxcare.29.0.2-tuxcare.3 |
9.0.2-tuxcare.4 |
nodemailerTuxCare:npm |
9.0.2-tuxcare.0 up to 9.0.2-tuxcare.6, plus listed versions 9.0.29.0.2-tuxcare.19.0.2-tuxcare.29.0.2-tuxcare.39.0.2-tuxcare.49.0.2-tuxcare.5 |
9.0.2-tuxcare.6 |
nodemailerTuxCare:npm |
9.0.6-tuxcare.0 up to 9.0.6-tuxcare.5, plus listed versions 9.0.69.0.6-tuxcare.19.0.6-tuxcare.29.0.6-tuxcare.39.0.6-tuxcare.4 |
9.0.6-tuxcare.5 |
nodemailerTuxCare:npm |
9.1.0-tuxcare.0 up to 9.1.0-tuxcare.7, plus listed versions 9.1.09.1.0-tuxcare.19.1.0-tuxcare.29.1.0-tuxcare.39.1.0-tuxcare.49.1.0-tuxcare.59.1.0-tuxcare.6 |
9.1.0-tuxcare.7 |
Show 20 moreShow less
| Package | Affected | Fixed |
|---|---|---|
nodemailerTuxCare:npm |
9.0.5-tuxcare.0 up to 9.0.5-tuxcare.6, plus listed versions 9.0.59.0.5-tuxcare.19.0.5-tuxcare.29.0.5-tuxcare.39.0.5-tuxcare.49.0.5-tuxcare.5 |
9.0.5-tuxcare.6 |
nodemailerTuxCare:npm |
9.0.0-tuxcare.0 up to 9.0.0-tuxcare.6, plus listed versions 9.0.09.0.0-tuxcare.19.0.0-tuxcare.29.0.0-tuxcare.39.0.0-tuxcare.49.0.0-tuxcare.5 |
9.0.0-tuxcare.6 |
nodemailerTuxCare:npm |
9.0.3-tuxcare.0 up to 9.0.3-tuxcare.6, plus listed versions 9.0.39.0.3-tuxcare.19.0.3-tuxcare.29.0.3-tuxcare.39.0.3-tuxcare.49.0.3-tuxcare.5 |
9.0.3-tuxcare.6 |
nodemailerTuxCare:npm |
9.0.1-tuxcare.0 up to 9.0.1-tuxcare.5, plus listed versions 9.0.19.0.1-tuxcare.19.0.1-tuxcare.29.0.1-tuxcare.39.0.1-tuxcare.4 |
9.0.1-tuxcare.5 |
nodemailerTuxCare:npm |
6.10.1-tuxcare.0 up to 6.10.1-tuxcare.15, plus listed versions 6.10.16.10.1-tuxcare.16.10.1-tuxcare.106.10.1-tuxcare.116.10.1-tuxcare.12 Show 10 moreShow less6.10.1-tuxcare.136.10.1-tuxcare.146.10.1-tuxcare.26.10.1-tuxcare.36.10.1-tuxcare.46.10.1-tuxcare.56.10.1-tuxcare.66.10.1-tuxcare.76.10.1-tuxcare.86.10.1-tuxcare.9 |
6.10.1-tuxcare.15 |
nodemailerTuxCare:npm |
9.0.5-tuxcare.0 up to 9.0.5-tuxcare.7, plus listed versions 9.0.59.0.5-tuxcare.19.0.5-tuxcare.29.0.5-tuxcare.39.0.5-tuxcare.49.0.5-tuxcare.59.0.5-tuxcare.6 |
9.0.5-tuxcare.7 |
nodemailerTuxCare:npm |
9.0.2-tuxcare.0 up to 9.0.2-tuxcare.7, plus listed versions 9.0.29.0.2-tuxcare.19.0.2-tuxcare.29.0.2-tuxcare.39.0.2-tuxcare.49.0.2-tuxcare.59.0.2-tuxcare.6 |
9.0.2-tuxcare.7 |
nodemailerTuxCare:npm |
9.0.6-tuxcare.0 up to 9.0.6-tuxcare.6, plus listed versions 9.0.69.0.6-tuxcare.19.0.6-tuxcare.29.0.6-tuxcare.39.0.6-tuxcare.49.0.6-tuxcare.5 |
9.0.6-tuxcare.6 |
nodemailerTuxCare:npm |
9.0.0-tuxcare.0 up to 9.0.0-tuxcare.7, plus listed versions 9.0.09.0.0-tuxcare.19.0.0-tuxcare.29.0.0-tuxcare.39.0.0-tuxcare.49.0.0-tuxcare.59.0.0-tuxcare.6 |
9.0.0-tuxcare.7 |
nodemailerTuxCare:npm |
6.10.1-tuxcare.0 up to 6.10.1-tuxcare.16, plus listed versions 6.10.16.10.1-tuxcare.16.10.1-tuxcare.106.10.1-tuxcare.116.10.1-tuxcare.12 Show 11 moreShow less6.10.1-tuxcare.136.10.1-tuxcare.146.10.1-tuxcare.156.10.1-tuxcare.26.10.1-tuxcare.36.10.1-tuxcare.46.10.1-tuxcare.56.10.1-tuxcare.66.10.1-tuxcare.76.10.1-tuxcare.86.10.1-tuxcare.9 |
6.10.1-tuxcare.16 |
nodemailerTuxCare:npm |
2.7.2-tuxcare.0 up to 2.7.2-tuxcare.10, plus listed versions 2.7.22.7.2-tuxcare.12.7.2-tuxcare.22.7.2-tuxcare.32.7.2-tuxcare.4 Show 5 moreShow less2.7.2-tuxcare.52.7.2-tuxcare.62.7.2-tuxcare.72.7.2-tuxcare.82.7.2-tuxcare.9 |
2.7.2-tuxcare.10 |
node-nodemailerDebian:12 |
All versions, plus listed versions 10.0.0+~8.0.1-110.0.10+~8.0.1-110.0.10+~8.0.2-110.0.13+~8.0.2-110.0.14+~8.0.2-1 Show 25 moreShow less10.1.7+~8.0.2-16.10.0+~6.4.17-16.8.0+~6.4.6-16.9.13+~6.4.14-16.9.15+~6.4.16-16.9.16+~6.4.16-16.9.4+~6.4.9-16.9.4+~6.4.9-26.9.4+~6.4.9-36.9.4+~6.4.9-47.0.10+~7.0.2-17.0.12+~7.0.5-17.0.5+~7.0.1-17.0.6+~7.0.1-17.0.9+~7.0.2-17.0.9+~7.0.2-28.0.11+~8.0.1-18.0.2+~7.0.11-18.0.3+~7.0.11-18.0.4+~7.0.11-18.0.4+~7.0.11-29.0.0+~8.0.1-19.0.3+~8.0.1-19.0.5+~8.0.1-19.0.6+~8.0.1-1 |
None known |
node-nodemailerDebian:13 |
All versions, plus listed versions 10.0.0+~8.0.1-110.0.10+~8.0.1-110.0.10+~8.0.2-110.0.13+~8.0.2-110.0.14+~8.0.2-1 Show 18 moreShow less10.1.7+~8.0.2-16.10.0+~6.4.17-16.10.0+~6.4.17-1+deb13u17.0.10+~7.0.2-17.0.12+~7.0.5-17.0.5+~7.0.1-17.0.6+~7.0.1-17.0.9+~7.0.2-17.0.9+~7.0.2-28.0.11+~8.0.1-18.0.2+~7.0.11-18.0.3+~7.0.11-18.0.4+~7.0.11-18.0.4+~7.0.11-29.0.0+~8.0.1-19.0.3+~8.0.1-19.0.5+~8.0.1-19.0.6+~8.0.1-1 |
None known |
node-nodemailerDebian:14 |
before 10.0.10+~8.0.1-1, plus listed versions 10.0.0+~8.0.1-16.10.0+~6.4.17-17.0.10+~7.0.2-17.0.12+~7.0.5-17.0.5+~7.0.1-1 Show 12 moreShow less7.0.6+~7.0.1-17.0.9+~7.0.2-17.0.9+~7.0.2-28.0.11+~8.0.1-18.0.2+~7.0.11-18.0.3+~7.0.11-18.0.4+~7.0.11-18.0.4+~7.0.11-29.0.0+~8.0.1-19.0.3+~8.0.1-19.0.5+~8.0.1-19.0.6+~8.0.1-1 |
10.0.10+~8.0.1-1 |
nodemailernpm |
3.0.0 up to 10.0.10 | 10.0.10 |
node-nodemailerUbuntu:20.04:LTS |
All versions, plus listed versions 6.3.0-26.3.1-16.4.0-16.4.1-16.4.2-16.4.5-1 |
None known |
node-nodemailerUbuntu:22.04:LTS |
All versions, plus listed versions 6.4.17-36.7.0-16.7.0-26.7.1+~6.4.4-1 |
None known |
node-nodemailerUbuntu:24.04:LTS |
All versions, plus listed versions 6.9.4+~6.4.9-26.9.4+~6.4.9-3ubuntu16.9.4+~6.4.9-4 |
None known |
node-nodemailerUbuntu:26.10 |
All versions, plus listed versions 8.0.4+~7.0.11-18.0.4+~7.0.11-29.0.0+~8.0.1-19.0.3+~8.0.1-19.0.5+~8.0.1-1 |
None known |
node-nodemailerUbuntu:26.04:LTS |
All versions, plus listed versions 7.0.5+~7.0.1-17.0.9+~7.0.2-27.0.10+~7.0.2-17.0.12+~7.0.5-18.0.4+~7.0.11-1 |
None known |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| affected, aliases | OSV | |
| facts | ||
| affected, aliases, references | ||
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-110872 is a high vulnerability (CVSS 8.2) in Nodemailer, published October 14, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.36%, the 29th percentile. Fixed in nodemailer 10.0.10.
References
github.com/nodemailer/nodemailer/security/advisories/GHSA-4g23-2xm8-66gc
vulncheck.com/advisories/nodemailer-3.0.0-before-10.0.10-denial-of-service-via-smtp-reply-parsing
nvd.nist.gov/vuln/detail/CVE-2026-110872
github.com/advisories/GHSA-37fc-hcrp-mmff
github.com/nodemailer/nodemailer/commit/f2d82fa84d47015a7bbb4253da61eeb778c658b1
github.com/nodemailer/nodemailer/releases/tag/v10.0.10
Show 15 moreShow less
github.com/advisories/GHSA-4g23-2xm8-66gc
github.com/nodemailer/nodemailer/security/advisories/GHSA-85x2-q946-cp5h
github.com/nodemailer/nodemailer/commit/1cd57d2b8c49dff048c21cdbafdb54439a7f07e2
github.com/nodemailer/nodemailer/releases/tag/v10.1.4
github.com/advisories/GHSA-85x2-q946-cp5h
github.com/nodemailer/nodemailer/security/advisories/GHSA-8c8m-p3m8-cjg8
github.com/nodemailer/nodemailer/commit/0a8761762ac78f2db2ba37f712f2a52a404ce011
github.com/advisories/GHSA-8c8m-p3m8-cjg8
github.com/nodemailer/nodemailer/security/advisories/GHSA-m943-m63m-w62w
github.com/advisories/GHSA-m943-m63m-w62w
github.com/CVEProject/cvelistV5/tree/main/cves/2026/110xxx/CVE-2026-110872.json
security-tracker.debian.org/tracker/CVE-2026-110872
github.com/nodemailer/nodemailer
ubuntu.com/security/CVE-2026-110872
cve.org/CVERecord?id=CVE-2026-110872
Left out here: the rest of 2 source descriptions. The JSON record has them.