nodemailer 7.0.10 → 7.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## [7.0.11](https://github.com/nodemailer/nodemailer/compare/v7.0.10...v7.0.11) (2025-11-26)
4
+
5
+
6
+ ### Bug Fixes
7
+
8
+ * prevent stack overflow DoS in addressparser with deeply nested groups ([b61b9c0](https://github.com/nodemailer/nodemailer/commit/b61b9c0cfd682b6f647754ca338373b68336a150))
9
+
3
10
  ## [7.0.10](https://github.com/nodemailer/nodemailer/compare/v7.0.9...v7.0.10) (2025-10-23)
4
11
 
5
12
 
@@ -4,9 +4,10 @@
4
4
  * Converts tokens for a single address into an address object
5
5
  *
6
6
  * @param {Array} tokens Tokens object
7
+ * @param {Number} depth Current recursion depth for nested group protection
7
8
  * @return {Object} Address object
8
9
  */
9
- function _handleAddress(tokens) {
10
+ function _handleAddress(tokens, depth) {
10
11
  let isGroup = false;
11
12
  let state = 'text';
12
13
  let address;
@@ -87,7 +88,7 @@ function _handleAddress(tokens) {
87
88
  // Parse group members, but flatten any nested groups (RFC 5322 doesn't allow nesting)
88
89
  let groupMembers = [];
89
90
  if (data.group.length) {
90
- let parsedGroup = addressparser(data.group.join(','));
91
+ let parsedGroup = addressparser(data.group.join(','), { _depth: depth + 1 });
91
92
  // Flatten: if any member is itself a group, extract its members into the sequence
92
93
  parsedGroup.forEach(member => {
93
94
  if (member.group) {
@@ -299,6 +300,13 @@ class Tokenizer {
299
300
  }
300
301
  }
301
302
 
303
+ /**
304
+ * Maximum recursion depth for parsing nested groups.
305
+ * RFC 5322 doesn't allow nested groups, so this is a safeguard against
306
+ * malicious input that could cause stack overflow.
307
+ */
308
+ const MAX_NESTED_GROUP_DEPTH = 50;
309
+
302
310
  /**
303
311
  * Parses structured e-mail addresses from an address field
304
312
  *
@@ -311,10 +319,18 @@ class Tokenizer {
311
319
  * [{name: 'Name', address: 'address@domain'}]
312
320
  *
313
321
  * @param {String} str Address field
322
+ * @param {Object} options Optional options object
323
+ * @param {Number} options._depth Internal recursion depth counter (do not set manually)
314
324
  * @return {Array} An array of address objects
315
325
  */
316
326
  function addressparser(str, options) {
317
327
  options = options || {};
328
+ let depth = options._depth || 0;
329
+
330
+ // Prevent stack overflow from deeply nested groups (DoS protection)
331
+ if (depth > MAX_NESTED_GROUP_DEPTH) {
332
+ return [];
333
+ }
318
334
 
319
335
  let tokenizer = new Tokenizer(str);
320
336
  let tokens = tokenizer.tokenize();
@@ -339,7 +355,7 @@ function addressparser(str, options) {
339
355
  }
340
356
 
341
357
  addresses.forEach(address => {
342
- address = _handleAddress(address);
358
+ address = _handleAddress(address, depth);
343
359
  if (address.length) {
344
360
  parsedAddresses = parsedAddresses.concat(address);
345
361
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nodemailer",
3
- "version": "7.0.10",
3
+ "version": "7.0.11",
4
4
  "description": "Easy as cake e-mail sending from your Node.js applications",
5
5
  "main": "lib/nodemailer.js",
6
6
  "scripts": {
@@ -26,12 +26,12 @@
26
26
  },
27
27
  "homepage": "https://nodemailer.com/",
28
28
  "devDependencies": {
29
- "@aws-sdk/client-sesv2": "3.914.0",
29
+ "@aws-sdk/client-sesv2": "3.940.0",
30
30
  "bunyan": "1.8.15",
31
31
  "c8": "10.1.3",
32
- "eslint": "9.38.0",
32
+ "eslint": "9.39.1",
33
33
  "eslint-config-prettier": "10.1.8",
34
- "globals": "16.4.0",
34
+ "globals": "16.5.0",
35
35
  "libbase64": "1.3.0",
36
36
  "libmime": "5.3.7",
37
37
  "libqp": "2.1.1",
@@ -39,7 +39,7 @@
39
39
  "prettier": "3.6.2",
40
40
  "proxy": "1.0.2",
41
41
  "proxy-test-server": "1.0.0",
42
- "smtp-server": "3.15.0"
42
+ "smtp-server": "3.16.1"
43
43
  },
44
44
  "engines": {
45
45
  "node": ">=6.0.0"