step-node-agent 3.29.0 → 3.29.2

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.
Files changed (64) hide show
  1. package/node_modules/body-parser/HISTORY.md +8 -0
  2. package/node_modules/body-parser/lib/types/urlencoded.js +2 -9
  3. package/node_modules/body-parser/package.json +9 -10
  4. package/node_modules/cookie/index.js +2 -1
  5. package/node_modules/cookie/package.json +1 -1
  6. package/node_modules/cookie-signature/History.md +5 -1
  7. package/node_modules/cookie-signature/index.js +6 -6
  8. package/node_modules/cookie-signature/package.json +2 -2
  9. package/node_modules/express/History.md +11 -0
  10. package/node_modules/express/package.json +17 -17
  11. package/node_modules/finalhandler/HISTORY.md +6 -0
  12. package/node_modules/finalhandler/package.json +3 -3
  13. package/node_modules/http-errors/HISTORY.md +6 -0
  14. package/node_modules/http-errors/index.js +4 -3
  15. package/node_modules/http-errors/package.json +12 -8
  16. package/node_modules/qs/.github/SECURITY.md +11 -0
  17. package/node_modules/qs/.github/THREAT_MODEL.md +78 -0
  18. package/node_modules/qs/CHANGELOG.md +31 -0
  19. package/node_modules/qs/README.md +25 -1
  20. package/node_modules/qs/dist/qs.js +95 -44
  21. package/node_modules/qs/eslint.config.mjs +56 -0
  22. package/node_modules/qs/lib/parse.js +107 -43
  23. package/node_modules/qs/lib/stringify.js +11 -6
  24. package/node_modules/qs/lib/utils.js +61 -6
  25. package/node_modules/qs/package.json +15 -12
  26. package/node_modules/qs/test/parse.js +257 -31
  27. package/node_modules/qs/test/stringify.js +23 -11
  28. package/node_modules/qs/test/utils.js +245 -0
  29. package/node_modules/raw-body/package.json +5 -7
  30. package/node_modules/send/HISTORY.md +19 -7
  31. package/node_modules/send/package.json +6 -6
  32. package/node_modules/serve-static/HISTORY.md +6 -0
  33. package/node_modules/serve-static/package.json +2 -2
  34. package/node_modules/statuses/HISTORY.md +5 -0
  35. package/node_modules/statuses/README.md +3 -0
  36. package/node_modules/statuses/package.json +7 -7
  37. package/node_modules/yaml/browser/dist/compose/compose-collection.js +1 -1
  38. package/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +1 -1
  39. package/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +2 -2
  40. package/node_modules/yaml/browser/dist/errors.js +1 -1
  41. package/node_modules/yaml/browser/dist/nodes/Alias.js +1 -1
  42. package/node_modules/yaml/browser/dist/parse/parser.js +2 -2
  43. package/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +1 -1
  44. package/node_modules/yaml/browser/dist/stringify/stringifyPair.js +1 -1
  45. package/node_modules/yaml/dist/compose/compose-collection.js +1 -1
  46. package/node_modules/yaml/dist/compose/resolve-block-seq.js +1 -1
  47. package/node_modules/yaml/dist/compose/resolve-flow-collection.js +2 -2
  48. package/node_modules/yaml/dist/errors.js +1 -1
  49. package/node_modules/yaml/dist/nodes/Alias.js +1 -1
  50. package/node_modules/yaml/dist/parse/parser.js +2 -2
  51. package/node_modules/yaml/dist/stringify/stringifyNumber.js +1 -1
  52. package/node_modules/yaml/dist/stringify/stringifyPair.js +1 -1
  53. package/node_modules/yaml/package.json +4 -4
  54. package/package.json +1 -1
  55. package/node_modules/body-parser/SECURITY.md +0 -25
  56. package/node_modules/cookie-signature/.npmignore +0 -4
  57. package/node_modules/qs/.eslintrc +0 -38
  58. package/node_modules/raw-body/HISTORY.md +0 -308
  59. package/node_modules/raw-body/SECURITY.md +0 -24
  60. package/node_modules/send/node_modules/encodeurl/HISTORY.md +0 -14
  61. package/node_modules/send/node_modules/encodeurl/LICENSE +0 -22
  62. package/node_modules/send/node_modules/encodeurl/README.md +0 -128
  63. package/node_modules/send/node_modules/encodeurl/index.js +0 -60
  64. package/node_modules/send/node_modules/encodeurl/package.json +0 -40
@@ -1,3 +1,11 @@
1
+ 1.20.4 / 2025-12-01
2
+ ===================
3
+
4
+ * deps: qs@~6.14.0
5
+ * deps: use tilde notation for dependencies
6
+ * deps: http-errors@~2.0.1
7
+ * deps: raw-body@~2.5.3
8
+
1
9
  1.20.3 / 2024-09-10
2
10
  ===================
3
11
 
@@ -55,9 +55,6 @@ function urlencoded (options) {
55
55
  : opts.limit
56
56
  var type = opts.type || 'application/x-www-form-urlencoded'
57
57
  var verify = opts.verify || false
58
- var depth = typeof opts.depth !== 'number'
59
- ? Number(opts.depth || 32)
60
- : opts.depth
61
58
 
62
59
  if (verify !== false && typeof verify !== 'function') {
63
60
  throw new TypeError('option verify must be function')
@@ -121,8 +118,7 @@ function urlencoded (options) {
121
118
  encoding: charset,
122
119
  inflate: inflate,
123
120
  limit: limit,
124
- verify: verify,
125
- depth: depth
121
+ verify: verify
126
122
  })
127
123
  }
128
124
  }
@@ -137,10 +133,7 @@ function extendedparser (options) {
137
133
  var parameterLimit = options.parameterLimit !== undefined
138
134
  ? options.parameterLimit
139
135
  : 1000
140
-
141
- var depth = typeof options.depth !== 'number'
142
- ? Number(options.depth || 32)
143
- : options.depth
136
+ var depth = options.depth !== undefined ? options.depth : 32
144
137
  var parse = parser('qs')
145
138
 
146
139
  if (isNaN(parameterLimit) || parameterLimit < 1) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "body-parser",
3
3
  "description": "Node.js body parsing middleware",
4
- "version": "1.20.3",
4
+ "version": "1.20.4",
5
5
  "contributors": [
6
6
  "Douglas Christopher Wilson <doug@somethingdoug.com>",
7
7
  "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
@@ -9,18 +9,18 @@
9
9
  "license": "MIT",
10
10
  "repository": "expressjs/body-parser",
11
11
  "dependencies": {
12
- "bytes": "3.1.2",
12
+ "bytes": "~3.1.2",
13
13
  "content-type": "~1.0.5",
14
14
  "debug": "2.6.9",
15
15
  "depd": "2.0.0",
16
- "destroy": "1.2.0",
17
- "http-errors": "2.0.0",
18
- "iconv-lite": "0.4.24",
19
- "on-finished": "2.4.1",
20
- "qs": "6.13.0",
21
- "raw-body": "2.5.2",
16
+ "destroy": "~1.2.0",
17
+ "http-errors": "~2.0.1",
18
+ "iconv-lite": "~0.4.24",
19
+ "on-finished": "~2.4.1",
20
+ "qs": "~6.14.0",
21
+ "raw-body": "~2.5.3",
22
22
  "type-is": "~1.6.18",
23
- "unpipe": "1.0.0"
23
+ "unpipe": "~1.0.0"
24
24
  },
25
25
  "devDependencies": {
26
26
  "eslint": "8.34.0",
@@ -40,7 +40,6 @@
40
40
  "lib/",
41
41
  "LICENSE",
42
42
  "HISTORY.md",
43
- "SECURITY.md",
44
43
  "index.js"
45
44
  ],
46
45
  "engines": {
@@ -21,6 +21,7 @@ exports.serialize = serialize;
21
21
  */
22
22
 
23
23
  var __toString = Object.prototype.toString
24
+ var __hasOwnProperty = Object.prototype.hasOwnProperty
24
25
 
25
26
  /**
26
27
  * RegExp to match cookie-name in RFC 6265 sec 4.1.1
@@ -130,7 +131,7 @@ function parse(str, opt) {
130
131
  var key = str.slice(keyStartIdx, keyEndIdx);
131
132
 
132
133
  // only assign once
133
- if (!obj.hasOwnProperty(key)) {
134
+ if (!__hasOwnProperty.call(obj, key)) {
134
135
  var valStartIdx = startIndex(str, eqIdx + 1, endIdx);
135
136
  var valEndIdx = endIndex(str, endIdx, valStartIdx);
136
137
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cookie",
3
3
  "description": "HTTP server cookie parsing and serialization",
4
- "version": "0.7.1",
4
+ "version": "0.7.2",
5
5
  "author": "Roman Shtylman <shtylman@gmail.com>",
6
6
  "contributors": [
7
7
  "Douglas Christopher Wilson <doug@somethingdoug.com>"
@@ -1,10 +1,14 @@
1
+ 1.0.7 / 2023-04-12
2
+ ==================
3
+
4
+ * backport the buffer support from the 1.2.x release branch (thanks @FadhiliNjagi!)
5
+
1
6
  1.0.6 / 2015-02-03
2
7
  ==================
3
8
 
4
9
  * use `npm test` instead of `make test` to run tests
5
10
  * clearer assertion messages when checking input
6
11
 
7
-
8
12
  1.0.5 / 2014-09-05
9
13
  ==================
10
14
 
@@ -8,14 +8,14 @@ var crypto = require('crypto');
8
8
  * Sign the given `val` with `secret`.
9
9
  *
10
10
  * @param {String} val
11
- * @param {String} secret
11
+ * @param {String|NodeJS.ArrayBufferView|crypto.KeyObject} secret
12
12
  * @return {String}
13
13
  * @api private
14
14
  */
15
15
 
16
16
  exports.sign = function(val, secret){
17
- if ('string' != typeof val) throw new TypeError("Cookie value must be provided as a string.");
18
- if ('string' != typeof secret) throw new TypeError("Secret string must be provided.");
17
+ if ('string' !== typeof val) throw new TypeError("Cookie value must be provided as a string.");
18
+ if (null == secret) throw new TypeError("Secret key must be provided.");
19
19
  return val + '.' + crypto
20
20
  .createHmac('sha256', secret)
21
21
  .update(val)
@@ -28,14 +28,14 @@ exports.sign = function(val, secret){
28
28
  * returning `false` if the signature is invalid.
29
29
  *
30
30
  * @param {String} val
31
- * @param {String} secret
31
+ * @param {String|NodeJS.ArrayBufferView|crypto.KeyObject} secret
32
32
  * @return {String|Boolean}
33
33
  * @api private
34
34
  */
35
35
 
36
36
  exports.unsign = function(val, secret){
37
- if ('string' != typeof val) throw new TypeError("Signed cookie string must be provided.");
38
- if ('string' != typeof secret) throw new TypeError("Secret string must be provided.");
37
+ if ('string' !== typeof val) throw new TypeError("Signed cookie string must be provided.");
38
+ if (null == secret) throw new TypeError("Secret key must be provided.");
39
39
  var str = val.slice(0, val.lastIndexOf('.'))
40
40
  , mac = exports.sign(str, secret);
41
41
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cookie-signature",
3
- "version": "1.0.6",
3
+ "version": "1.0.7",
4
4
  "description": "Sign and unsign cookies",
5
5
  "keywords": ["cookie", "sign", "unsign"],
6
6
  "author": "TJ Holowaychuk <tj@learnboost.com>",
@@ -15,4 +15,4 @@
15
15
  "test": "mocha --require should --reporter spec"
16
16
  },
17
17
  "main": "index"
18
- }
18
+ }
@@ -1,3 +1,14 @@
1
+ 4.22.1 / 2025-12-01
2
+ ==========
3
+
4
+ * Revert security fix for [CVE-2024-51999](https://www.cve.org/CVERecord?id=CVE-2024-51999) ([GHSA-pj86-cfqh-vqx6](https://github.com/expressjs/express/security/advisories/GHSA-pj86-cfqh-vqx6))
5
+
6
+ 4.22.0 / 2025-12-01
7
+ ==========
8
+ * Security fix for [CVE-2024-51999](https://www.cve.org/CVERecord?id=CVE-2024-51999) ([GHSA-pj86-cfqh-vqx6](https://github.com/expressjs/express/security/advisories/GHSA-pj86-cfqh-vqx6))
9
+ * deps: use tilde notation for dependencies
10
+ * deps: qs@6.14.0
11
+
1
12
  4.21.2 / 2024-11-06
2
13
  ==========
3
14
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "express",
3
3
  "description": "Fast, unopinionated, minimalist web framework",
4
- "version": "4.21.2",
4
+ "version": "4.22.1",
5
5
  "author": "TJ Holowaychuk <tj@vision-media.ca>",
6
6
  "contributors": [
7
7
  "Aaron Heckmann <aaron.heckmann+github@gmail.com>",
@@ -34,32 +34,32 @@
34
34
  "dependencies": {
35
35
  "accepts": "~1.3.8",
36
36
  "array-flatten": "1.1.1",
37
- "body-parser": "1.20.3",
38
- "content-disposition": "0.5.4",
37
+ "body-parser": "~1.20.3",
38
+ "content-disposition": "~0.5.4",
39
39
  "content-type": "~1.0.4",
40
- "cookie": "0.7.1",
41
- "cookie-signature": "1.0.6",
40
+ "cookie": "~0.7.1",
41
+ "cookie-signature": "~1.0.6",
42
42
  "debug": "2.6.9",
43
43
  "depd": "2.0.0",
44
44
  "encodeurl": "~2.0.0",
45
45
  "escape-html": "~1.0.3",
46
46
  "etag": "~1.8.1",
47
- "finalhandler": "1.3.1",
48
- "fresh": "0.5.2",
49
- "http-errors": "2.0.0",
47
+ "finalhandler": "~1.3.1",
48
+ "fresh": "~0.5.2",
49
+ "http-errors": "~2.0.0",
50
50
  "merge-descriptors": "1.0.3",
51
51
  "methods": "~1.1.2",
52
- "on-finished": "2.4.1",
52
+ "on-finished": "~2.4.1",
53
53
  "parseurl": "~1.3.3",
54
- "path-to-regexp": "0.1.12",
54
+ "path-to-regexp": "~0.1.12",
55
55
  "proxy-addr": "~2.0.7",
56
- "qs": "6.13.0",
56
+ "qs": "~6.14.0",
57
57
  "range-parser": "~1.2.1",
58
58
  "safe-buffer": "5.2.1",
59
- "send": "0.19.0",
60
- "serve-static": "1.16.2",
59
+ "send": "~0.19.0",
60
+ "serve-static": "~1.16.2",
61
61
  "setprototypeof": "1.2.0",
62
- "statuses": "2.0.1",
62
+ "statuses": "~2.0.1",
63
63
  "type-is": "~1.6.18",
64
64
  "utils-merge": "1.0.1",
65
65
  "vary": "~1.1.2"
@@ -75,11 +75,11 @@
75
75
  "hbs": "4.2.0",
76
76
  "marked": "0.7.0",
77
77
  "method-override": "3.0.0",
78
- "mocha": "10.2.0",
78
+ "mocha": "^6.2.2",
79
79
  "morgan": "1.10.0",
80
- "nyc": "15.1.0",
80
+ "nyc": "^14.1.1",
81
81
  "pbkdf2-password": "1.2.1",
82
- "supertest": "6.3.0",
82
+ "supertest": "^6.1.6",
83
83
  "vhost": "~3.0.2"
84
84
  },
85
85
  "engines": {
@@ -1,3 +1,9 @@
1
+ v1.3.2 / 2025-12-01
2
+ ==================
3
+
4
+ * deps: use tilde notation for dependencies
5
+ * deps: statuses@~2.0.2
6
+
1
7
  v1.3.1 / 2024-09-11
2
8
  ==================
3
9
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "finalhandler",
3
3
  "description": "Node.js final http responder",
4
- "version": "1.3.1",
4
+ "version": "1.3.2",
5
5
  "author": "Douglas Christopher Wilson <doug@somethingdoug.com>",
6
6
  "license": "MIT",
7
7
  "repository": "pillarjs/finalhandler",
@@ -9,9 +9,9 @@
9
9
  "debug": "2.6.9",
10
10
  "encodeurl": "~2.0.0",
11
11
  "escape-html": "~1.0.3",
12
- "on-finished": "2.4.1",
12
+ "on-finished": "~2.4.1",
13
13
  "parseurl": "~1.3.3",
14
- "statuses": "2.0.1",
14
+ "statuses": "~2.0.2",
15
15
  "unpipe": "~1.0.0"
16
16
  },
17
17
  "devDependencies": {
@@ -1,3 +1,9 @@
1
+ 2.0.1 / 2025-11-20
2
+ ==================
3
+
4
+ * deps: use tilde notation for dependencies
5
+ * deps: update statuses to 2.0.2
6
+
1
7
  2.0.0 / 2021-12-17
2
8
  ==================
3
9
 
@@ -279,11 +279,12 @@ function populateConstructorExports (exports, codes, HttpError) {
279
279
 
280
280
  /**
281
281
  * Get a class name from a name identifier.
282
+ *
283
+ * @param {string} name
284
+ * @returns {string}
282
285
  * @private
283
286
  */
284
287
 
285
288
  function toClassName (name) {
286
- return name.substr(-5) !== 'Error'
287
- ? name + 'Error'
288
- : name
289
+ return name.slice(-5) === 'Error' ? name : name + 'Error'
289
290
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "http-errors",
3
3
  "description": "Create HTTP error objects",
4
- "version": "2.0.0",
4
+ "version": "2.0.1",
5
5
  "author": "Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)",
6
6
  "contributors": [
7
7
  "Alan Plum <me@pluma.io>",
@@ -9,17 +9,21 @@
9
9
  ],
10
10
  "license": "MIT",
11
11
  "repository": "jshttp/http-errors",
12
+ "funding": {
13
+ "type": "opencollective",
14
+ "url": "https://opencollective.com/express"
15
+ },
12
16
  "dependencies": {
13
- "depd": "2.0.0",
14
- "inherits": "2.0.4",
15
- "setprototypeof": "1.2.0",
16
- "statuses": "2.0.1",
17
- "toidentifier": "1.0.1"
17
+ "depd": "~2.0.0",
18
+ "inherits": "~2.0.4",
19
+ "setprototypeof": "~1.2.0",
20
+ "statuses": "~2.0.2",
21
+ "toidentifier": "~1.0.1"
18
22
  },
19
23
  "devDependencies": {
20
24
  "eslint": "7.32.0",
21
25
  "eslint-config-standard": "14.1.1",
22
- "eslint-plugin-import": "2.25.3",
26
+ "eslint-plugin-import": "2.32.0",
23
27
  "eslint-plugin-markdown": "2.2.1",
24
28
  "eslint-plugin-node": "11.1.0",
25
29
  "eslint-plugin-promise": "5.2.0",
@@ -32,7 +36,7 @@
32
36
  },
33
37
  "scripts": {
34
38
  "lint": "eslint . && node ./scripts/lint-readme-list.js",
35
- "test": "mocha --reporter spec --bail",
39
+ "test": "mocha --reporter spec",
36
40
  "test-ci": "nyc --reporter=lcov --reporter=text npm test",
37
41
  "test-cov": "nyc --reporter=html --reporter=text npm test",
38
42
  "version": "node scripts/version-history.js && git add HISTORY.md"
@@ -0,0 +1,11 @@
1
+ # Security
2
+
3
+ Please file a private vulnerability report via GitHub, email [@ljharb](https://github.com/ljharb), or see https://tidelift.com/security if you have a potential security vulnerability to report.
4
+
5
+ ## Incident Response Plan
6
+
7
+ Please see our [Incident Response Plan](https://github.com/ljharb/.github/blob/main/INCIDENT_RESPONSE_PLAN.md).
8
+
9
+ ## Threat Model
10
+
11
+ Please see [THREAT_MODEL.md](./THREAT_MODEL.md).
@@ -0,0 +1,78 @@
1
+ ## Threat Model for qs (querystring parsing library)
2
+
3
+ ### 1. Library Overview
4
+
5
+ - **Library Name:** qs
6
+ - **Brief Description:** A JavaScript library for parsing and stringifying URL query strings, supporting nested objects and arrays. It is widely used in Node.js and web applications for processing query parameters[2][6][8].
7
+ - **Key Public APIs/Functions:** `qs.parse()`, `qs.stringify()`
8
+
9
+ ### 2. Define Scope
10
+
11
+ This threat model focuses on the core parsing and stringifying functionality, specifically the handling of nested objects and arrays, option validation, and cycle management in stringification.
12
+
13
+ ### 3. Conceptual System Diagram
14
+
15
+ ```
16
+ Caller Application → qs.parse(input, options) → Parsing Engine → Output Object
17
+
18
+ └→ Options Handling
19
+
20
+ Caller Application → qs.stringify(obj, options) → Stringifying Engine → Output String
21
+
22
+ └→ Options Handling
23
+ └→ Cycle Tracking
24
+ ```
25
+
26
+ **Trust Boundaries:**
27
+ - **Input string (parse):** May come from untrusted sources (e.g., user input, network requests)
28
+ - **Input object (stringify):** May contain cycles, which can lead to infinite loops during stringification
29
+ - **Options:** Provided by the caller
30
+ - **Cycle Tracking:** Used only during stringification to detect and handle circular references
31
+
32
+ ### 4. Identify Assets
33
+
34
+ - **Integrity of parsed output:** Prevent malicious manipulation of the output object structure, especially ensuring builtins/globals are not modified as a result of parse[3][4][8].
35
+ - **Confidentiality of processed data:** Avoid leaking sensitive information through errors or output.
36
+ - **Availability/performance for host application:** Prevent crashes or resource exhaustion in the consuming application.
37
+ - **Security of host application:** Prevent the library from being a vector for attacks (e.g., prototype pollution, DoS).
38
+ - **Reputation of library:** Maintain trust by avoiding supply chain attacks and vulnerabilities[1].
39
+
40
+ ### 5. Identify Threats
41
+
42
+ | Component / API / Interaction | S | T | R | I | D | E |
43
+ |---------------------------------------|----|----|----|----|----|----|
44
+ | Public API Call (`parse`) | – | ✓ | – | ✓ | ✓ | ✓ |
45
+ | Public API Call (`stringify`) | – | ✓ | – | ✓ | ✓ | – |
46
+ | Options Handling | ✓ | ✓ | – | ✓ | – | ✓ |
47
+ | Dependency Interaction | – | – | – | – | ✓ | – |
48
+
49
+ **Key Threats:**
50
+ - **Tampering:** Malicious input can, if not prevented, alter parsed output (e.g., prototype pollution via `__proto__`, modification of builtins/globals)[3][4][8].
51
+ - **Information Disclosure:** Error messages may expose internal details or sensitive data.
52
+ - **Denial of Service:** Large or malformed input can exhaust memory or CPU.
53
+ - **Elevation of Privilege:** Prototype pollution can lead to unintended privilege escalation in the host application[3][4][8].
54
+
55
+ ### 6. Mitigation/Countermeasures
56
+
57
+ | Threat Identified | Proposed Mitigation |
58
+ |---------------------------------------------------|---------------------|
59
+ | Tampering (malicious input, prototype pollution) | Strict input validation; keep `allowPrototypes: false` by default; use `plainObjects` for output; ensure builtins/globals are never modified by parse[4][8]. |
60
+ | Information Disclosure (error messages) | Generic error messages without stack traces or internal paths. |
61
+ | Denial of Service (memory/CPU exhaustion) | Enforce `arrayLimit` and `parameterLimit` with safe defaults; enable `throwOnLimitExceeded`; limit nesting depth[7]. |
62
+ | Elevation of Privilege (prototype pollution) | Keep `allowPrototypes: false`; validate options against allowlist; use `plainObjects` to avoid prototype pollution[4][8]. |
63
+
64
+ ### 7. Risk Ranking
65
+
66
+ - **High:** Denial of Service via array parsing or malformed input (historical vulnerability)
67
+ - **Medium:** Prototype pollution via options or input (if `allowPrototypes` enabled)
68
+ - **Low:** Information disclosure in errors
69
+
70
+ ### 8. Next Steps & Review
71
+
72
+ 1. **Audit option validation logic.**
73
+ 2. **Add depth limiting to nested parsing and stringification.**
74
+ 3. **Implement fuzz testing for parser and stringifier edge cases.**
75
+ 4. **Regularly review dependencies for vulnerabilities.**
76
+ 5. **Keep documentation and threat model up to date.**
77
+ 6. **Ensure builtins/globals are never modified as a result of parse.**
78
+ 7. **Support round-trip consistency between parse and stringify as a non-security goal, with the right options[5][9].**
@@ -1,3 +1,34 @@
1
+ ## **6.14.1**
2
+ - [Fix] ensure arrayLength applies to `[]` notation as well
3
+ - [Fix] `parse`: when a custom decoder returns `null` for a key, ignore that key
4
+ - [Refactor] `parse`: extract key segment splitting helper
5
+ - [meta] add threat model
6
+ - [actions] add workflow permissions
7
+ - [Tests] `stringify`: increase coverage
8
+ - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `npmignore`, `es-value-fixtures`, `for-each`, `object-inspect`
9
+
10
+ ## **6.14.0**
11
+ - [New] `parse`: add `throwOnParameterLimitExceeded` option (#517)
12
+ - [Refactor] `parse`: use `utils.combine` more
13
+ - [patch] `parse`: add explicit `throwOnLimitExceeded` default
14
+ - [actions] use shared action; re-add finishers
15
+ - [meta] Fix changelog formatting bug
16
+ - [Deps] update `side-channel`
17
+ - [Dev Deps] update `es-value-fixtures`, `has-bigints`, `has-proto`, `has-symbols`
18
+ - [Tests] increase coverage
19
+
20
+ ## **6.13.1**
21
+ - [Fix] `stringify`: avoid a crash when a `filter` key is `null`
22
+ - [Fix] `utils.merge`: functions should not be stringified into keys
23
+ - [Fix] `parse`: avoid a crash with interpretNumericEntities: true, comma: true, and iso charset
24
+ - [Fix] `stringify`: ensure a non-string `filter` does not crash
25
+ - [Refactor] use `__proto__` syntax instead of `Object.create` for null objects
26
+ - [Refactor] misc cleanup
27
+ - [Tests] `utils.merge`: add some coverage
28
+ - [Tests] fix a test case
29
+ - [actions] split out node 10-20, and 20+
30
+ - [Dev Deps] update `es-value-fixtures`, `mock-property`, `object-inspect`, `tape`
31
+
1
32
  ## **6.13.0**
2
33
  - [New] `parse`: add `strictDepth` option (#511)
3
34
  - [Tests] use `npm audit` instead of `aud`
@@ -49,7 +49,7 @@ assert.deepEqual(qs.parse('foo[bar]=baz'), {
49
49
  });
50
50
  ```
51
51
 
52
- When using the `plainObjects` option the parsed value is returned as a null object, created via `Object.create(null)` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
52
+ When using the `plainObjects` option the parsed value is returned as a null object, created via `{ __proto__: null }` and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
53
53
 
54
54
  ```javascript
55
55
  var nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
@@ -135,6 +135,18 @@ var limited = qs.parse('a=b&c=d', { parameterLimit: 1 });
135
135
  assert.deepEqual(limited, { a: 'b' });
136
136
  ```
137
137
 
138
+ If you want an error to be thrown whenever the a limit is exceeded (eg, `parameterLimit`, `arrayLimit`), set the `throwOnLimitExceeded` option to `true`. This option will generate a descriptive error if the query string exceeds a configured limit.
139
+ ```javascript
140
+ try {
141
+ qs.parse('a=1&b=2&c=3&d=4', { parameterLimit: 3, throwOnLimitExceeded: true });
142
+ } catch (err) {
143
+ assert(err instanceof Error);
144
+ assert.strictEqual(err.message, 'Parameter limit exceeded. Only 3 parameters allowed.');
145
+ }
146
+ ```
147
+
148
+ When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `parameterLimit` and ignore the rest without throwing an error.
149
+
138
150
  To bypass the leading question mark, use `ignoreQueryPrefix`:
139
151
 
140
152
  ```javascript
@@ -286,6 +298,18 @@ var withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 });
286
298
  assert.deepEqual(withArrayLimit, { a: { '1': 'b' } });
287
299
  ```
288
300
 
301
+ If you want to throw an error whenever the array limit is exceeded, set the `throwOnLimitExceeded` option to `true`. This option will generate a descriptive error if the query string exceeds a configured limit.
302
+ ```javascript
303
+ try {
304
+ qs.parse('a[1]=b', { arrayLimit: 0, throwOnLimitExceeded: true });
305
+ } catch (err) {
306
+ assert(err instanceof Error);
307
+ assert.strictEqual(err.message, 'Array limit exceeded. Only 0 elements allowed in an array.');
308
+ }
309
+ ```
310
+
311
+ When `throwOnLimitExceeded` is set to `false` (default), **qs** will parse up to the specified `arrayLimit` and if the limit is exceeded, the array will instead be converted to an object with the index as the key
312
+
289
313
  To disable array parsing entirely, set `parseArrays` to `false`.
290
314
 
291
315
  ```javascript