Every CVE Search/ Get API key

CVE-2026-110870

Nodemailer before 10.0.13 Improper Input Validation via Angle-Bracket Address Comments

6.9 MediumFix available

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Attack profile

How easy it is to exploit

Attack vector
Network
Complexity
Low
Privileges needed
None
User interaction
None

What an attacker can affect

Confidentiality
None
Integrity
Low
Availability
None

Exploit likelihood

0.27%Unchanged since Oct 15, 2026
90%50%10%1%

What each source reports

CVE List Score used 6.9

Nodemailer before 10.0.13 Improper Input Validation via Angle-Bracket Address Comments

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
CVE-2026-110870
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-20
Updated
2026-11-02
EUVDEUVD-2026-101753 6.9

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
EUVD-2026-101753
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
Updated
2026-11-02
GitHub AdvisoriesGHSA-597p-2mmq-hhg9 6.9

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its...

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
GHSA-597p-2mmq-hhg9
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/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.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-20
Updated
2026-11-02
GitHub AdvisoriesGHSA-g73g-hqqh-jr95 5.3

Nodemailer: RFC 5322 comment inside an angle-bracket address is never stripped

Summary

Nodemailer's address parser has three published, patched fixes for RFC 5322 comment ( ... ) handling inside an addr-spec: GHSA-cc9r-2j5m-2m83 (comment glued two domain atoms into one), GHSA-g57g-f23g-4646 (the same glue for a quoted local part), and the related ReDoS fixes GHSA-prgh-xp8r-p3m5 / GHSA-v53p-9fqp-m79j. All three fixes live in _handleAddress()'s joins / _recoverAddrSpec() logic in src/addressparser/index.ts, and that logic is exercised whenever the local text-accumulation path in the tokenizer runs.

That logic is never reached at all for the single most common way a recipient is written: a display name followed by an angle-bracket address, Name <local@domain>. When the input inside the angle brackets itself contains an RFC 5322 comment, e.g.

Legit User <[email protected](x)evil.com>

the comment is not recognized as an operator, is not stripped, and the parenthesis characters survive verbatim inside the parsed address. That value is used as-is for envelope.to and is written raw onto the wire in the RCPT TO SMTP command. I confirmed this end to end:

  • against nodemailer's own jsonTransport/streamTransport (envelope.to and the emitted To: header both carry the malformed value), and
  • against a real SMTP server (aiosmtpd), where the malformed value is fatal to the transaction (501 Syntax: RCPT TO: <address> [SP <mail-parameters>], all recipients rejected).

This reproduces unmodified on every version I tested from 6.9.16 through the current 10.0.12 HEAD, i.e. it predates and survives all three of the address-parser advisories above unchanged, because it is a different root cause in a code path those fixes never touch.

Root cause

1. The tokenizer has a single-slot operator stack

src/addressparser/index.ts, Tokenizer.checkChar():

} else if (!this.operatorExpecting && !this.inDomainLiteral && chr in this.operators) {
    this.node = { type: 'operator', value: chr };
    this.list.push(this.node);
    this.node = null;
    this.operatorExpecting = this.operators[chr];
    this.escaped = false;
    return;
}

(currently around line 670)

operatorExpecting is a single string, not a stack. Once < opens the address scope, operatorExpecting is set to '>'. The branch above that recognizes a new operator character (such as () is gated on !this.operatorExpecting, which is now false. So while inside <...>, a ( is never tokenized as an operator at all — it is just an ordinary character appended to the running text token, together with everything up to the next >. The RFC 5322 comment is not recognized, not entered, and not stripped: it rides straight through as literal text.

2. The _handleAddress state machine loses the address state on any operator boundary

src/addressparser/index.ts, inside _handleAddress() (currently around line 365-388):

switch (token.value) {
    case '<':
        state = 'address';
        insideQuotes = false;
        break;
    case '(':
        state = 'comment';
        insideQuotes = false;
        break;
    ...
    default:
        state = 'text';
        insideQuotes = false;
        break;
}

Even where a comment is recognized (outside angle brackets), closing it with ) falls through to default and resets state to 'text', not back to whatever state was active before the comment opened. This is why the fixed cases (bare address, quoted local part) only work at all: the leaked comment tail lands in the free-text bucket, where _recoverAddrSpec()/the ADDR_SPEC extraction logic can find and strip it. Inside <...>, none of that applies in the first place (point 1), so there is no text-bucket safety net to fall back on — the whole point 1/point 2 interaction is what makes the angle-bracket case categorically different from, and unprotected by, the three existing fixes.

3. The one existing safety net requires whitespace, and this value has none

…

Record
GHSA-g73g-hqqh-jr95
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-20, CWE-436
Updated
2026-11-02
NVD 6.9

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
CVE-2026-110870
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/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.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-20
Updated
2026-11-02
OSV 6.9

Nodemailer before 10.0.13 Improper Input Validation via Angle-Bracket Address Comments

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
CVE-2026-110870
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
Weakness
CWE-20
Updated
2026-11-02
Show 11 moreShow less
OSVDEBIAN-CVE-2026-110870 6.9

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
DEBIAN-CVE-2026-110870
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/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-g73g-hqqh-jr95 5.3

Nodemailer: RFC 5322 comment inside an angle-bracket address is never stripped

Summary

Nodemailer's address parser has three published, patched fixes for RFC 5322 comment ( ... ) handling inside an addr-spec: GHSA-cc9r-2j5m-2m83 (comment glued two domain atoms into one), GHSA-g57g-f23g-4646 (the same glue for a quoted local part), and the related ReDoS fixes GHSA-prgh-xp8r-p3m5 / GHSA-v53p-9fqp-m79j. All three fixes live in _handleAddress()'s joins / _recoverAddrSpec() logic in src/addressparser/index.ts, and that logic is exercised whenever the local text-accumulation path in the tokenizer runs.

That logic is never reached at all for the single most common way a recipient is written: a display name followed by an angle-bracket address, Name <local@domain>. When the input inside the angle brackets itself contains an RFC 5322 comment, e.g.

Legit User <[email protected](x)evil.com>

the comment is not recognized as an operator, is not stripped, and the parenthesis characters survive verbatim inside the parsed address. That value is used as-is for envelope.to and is written raw onto the wire in the RCPT TO SMTP command. I confirmed this end to end:

  • against nodemailer's own jsonTransport/streamTransport (envelope.to and the emitted To: header both carry the malformed value), and
  • against a real SMTP server (aiosmtpd), where the malformed value is fatal to the transaction (501 Syntax: RCPT TO: <address> [SP <mail-parameters>], all recipients rejected).

This reproduces unmodified on every version I tested from 6.9.16 through the current 10.0.12 HEAD, i.e. it predates and survives all three of the address-parser advisories above unchanged, because it is a different root cause in a code path those fixes never touch.

Root cause

1. The tokenizer has a single-slot operator stack

src/addressparser/index.ts, Tokenizer.checkChar():

} else if (!this.operatorExpecting && !this.inDomainLiteral && chr in this.operators) {
    this.node = { type: 'operator', value: chr };
    this.list.push(this.node);
    this.node = null;
    this.operatorExpecting = this.operators[chr];
    this.escaped = false;
    return;
}

(currently around line 670)

operatorExpecting is a single string, not a stack. Once < opens the address scope, operatorExpecting is set to '>'. The branch above that recognizes a new operator character (such as () is gated on !this.operatorExpecting, which is now false. So while inside <...>, a ( is never tokenized as an operator at all — it is just an ordinary character appended to the running text token, together with everything up to the next >. The RFC 5322 comment is not recognized, not entered, and not stripped: it rides straight through as literal text.

2. The _handleAddress state machine loses the address state on any operator boundary

src/addressparser/index.ts, inside _handleAddress() (currently around line 365-388):

switch (token.value) {
    case '<':
        state = 'address';
        insideQuotes = false;
        break;
    case '(':
        state = 'comment';
        insideQuotes = false;
        break;
    ...
    default:
        state = 'text';
        insideQuotes = false;
        break;
}

Even where a comment is recognized (outside angle brackets), closing it with ) falls through to default and resets state to 'text', not back to whatever state was active before the comment opened. This is why the fixed cases (bare address, quoted local part) only work at all: the leaked comment tail lands in the free-text bucket, where _recoverAddrSpec()/the ADDR_SPEC extraction logic can find and strip it. Inside <...>, none of that applies in the first place (point 1), so there is no text-bucket safety net to fall back on — the whole point 1/point 2 interaction is what makes the angle-bracket case categorically different from, and unprotected by, the three existing fixes.

3. The one existing safety net requires whitespace, and this value has none

…

Record
GHSA-g73g-hqqh-jr95
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Weakness
CWE-20, CWE-436
Updated
2026-11-02
OSVUBUNTU-CVE-2026-110870 6.9

Nodemailer from 3.0.0 before 10.0.13 contains an improper input validation vulnerability in its address parser that fails to strip RFC 5322 comments inside angle-bracket addresses. Attackers can supply recipients like a display name with a parenthesized comment in the domain, so illegal characters reach envelope.to and RCPT TO, causing rejected delivery or parser interpretation conflicts that bypass domain allow-lists.

Record
UBUNTU-CVE-2026-110870
CVSS 4.0
6.9 MediumCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
CVSS 3.1
5.3 MediumCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:L/A:N
Updated
2026-11-02
OSVCLSA-2026-1793180903 No score

TuxCare security update for nodemailer (2 CVEs)

TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.1.0-tuxcare.8.

Record
CLSA-2026-1793180903
Updated
2026-11-02
OSVCLSA-2026-1793183905 No score

TuxCare security update for nodemailer (2 CVEs)

TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.6-tuxcare.7.

Record
CLSA-2026-1793183905
Updated
2026-11-02
OSVCLSA-2026-1793187944 No score

TuxCare security update for nodemailer (2 CVEs)

TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.5-tuxcare.8.

Record
CLSA-2026-1793187944
Updated
2026-11-02
OSVCLSA-2026-1793207112 No score

TuxCare security update for nodemailer (2 CVEs)

TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.3-tuxcare.7.

Record
CLSA-2026-1793207112
Updated
2026-11-02
OSVCLSA-2026-1793209433 No score

TuxCare security update for nodemailer (2 CVEs)

TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 9.0.2-tuxcare.8.

Record
CLSA-2026-1793209433
Updated
2026-11-02
OSVCLSA-2026-1793215120 No score

TuxCare security update for nodemailer (1 CVE)

TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 9.0.1-tuxcare.6.

Record
CLSA-2026-1793215120
Updated
2026-11-02
OSVCLSA-2026-1793267771 No score

TuxCare security update for nodemailer (1 CVE)

TuxCare rebuilt nodemailer to address 1 CVE. Fixed in 9.0.0-tuxcare.8.

Record
CLSA-2026-1793267771
Updated
2026-11-02
OSVCLSA-2026-1793446166 No score

TuxCare security update for nodemailer (2 CVEs)

TuxCare rebuilt nodemailer to address 2 CVEs. Fixed in 6.10.1-tuxcare.17.

Record
CLSA-2026-1793446166
Updated
2026-11-02

Affected products

Affected packages

Affected packages
PackageAffectedFixed
nodemailer
npm
3.0.0 to 10.0.12
10.0.13
nodemailer
TuxCare:npm
9.1.0-tuxcare.0 up to 9.1.0-tuxcare.8, 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.69.1.0-tuxcare.7
9.1.0-tuxcare.8
nodemailer
TuxCare:npm
9.0.6-tuxcare.0 up to 9.0.6-tuxcare.7, 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.59.0.6-tuxcare.6
9.0.6-tuxcare.7
nodemailer
TuxCare:npm
9.0.5-tuxcare.0 up to 9.0.5-tuxcare.8, 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.69.0.5-tuxcare.7
9.0.5-tuxcare.8
nodemailer
TuxCare:npm
9.0.3-tuxcare.0 up to 9.0.3-tuxcare.7, 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.59.0.3-tuxcare.6
9.0.3-tuxcare.7
nodemailer
TuxCare:npm
9.0.2-tuxcare.0 up to 9.0.2-tuxcare.8, 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.69.0.2-tuxcare.7
9.0.2-tuxcare.8
nodemailer
TuxCare:npm
9.0.1-tuxcare.0 up to 9.0.1-tuxcare.6, plus listed versions
9.0.19.0.1-tuxcare.19.0.1-tuxcare.29.0.1-tuxcare.39.0.1-tuxcare.49.0.1-tuxcare.5
9.0.1-tuxcare.6
nodemailer
TuxCare:npm
9.0.0-tuxcare.0 up to 9.0.0-tuxcare.8, 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.69.0.0-tuxcare.7
9.0.0-tuxcare.8
nodemailer
TuxCare:npm
From an advisory covering 2 CVEs
6.10.1-tuxcare.0 up to 6.10.1-tuxcare.17, plus listed versions
6.10.16.10.1-tuxcare.16.10.1-tuxcare.106.10.1-tuxcare.116.10.1-tuxcare.12
Show 12 moreShow less
6.10.1-tuxcare.136.10.1-tuxcare.146.10.1-tuxcare.156.10.1-tuxcare.166.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.17
node-nodemailer
Debian: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 less
10.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
Show 8 moreShow less
Affected packages
PackageAffectedFixed
node-nodemailer
Debian: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 less
10.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-nodemailer
Debian:14
before 10.0.13+~8.0.2-1, plus listed versions
10.0.0+~8.0.1-110.0.10+~8.0.1-110.0.10+~8.0.2-16.10.0+~6.4.17-17.0.10+~7.0.2-1
Show 14 moreShow less
7.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
10.0.13+~8.0.2-1
nodemailer
npm
3.0.0 up to 10.0.13
10.0.13
node-nodemailer
Ubuntu: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-nodemailer
Ubuntu: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-nodemailer
Ubuntu: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-nodemailer
Ubuntu: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-nodemailer
Ubuntu: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

History
RecordedChangedSources
affected, facts
affected, aliases, references
first indexedCVE List, EUVD, GitHub Advisories, NVD, OSV

Dates are when Every CVE recorded each change. Upstream dates may differ.

In short

CVE-2026-110870 is a medium vulnerability (CVSS 6.9) 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.27%, the 18th percentile. Fixed in nodemailer 10.0.13.

References

Show 6 moreShow less
This page doesn't list everything

Left out here: the rest of 2 source descriptions. The JSON record has them.

MoveEnter Open