@contrast/agent-bundle 5.45.1 → 5.47.0

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 (189) hide show
  1. package/README.md +1 -1
  2. package/node_modules/@contrast/agent/README.md +1 -1
  3. package/node_modules/@contrast/agent/package.json +12 -12
  4. package/node_modules/@contrast/agentify/package.json +15 -15
  5. package/node_modules/@contrast/architecture-components/package.json +5 -5
  6. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/common.js +1 -1
  7. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/handlers.js +24 -11
  8. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/index.js +6 -4
  9. package/node_modules/@contrast/assess/lib/configuration-analysis/install/apollo-server.js +92 -0
  10. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/install/express-session.js +2 -2
  11. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/install/fastify-cookie.js +2 -2
  12. package/node_modules/@contrast/assess/lib/configuration-analysis/install/graphql-yoga.js +90 -0
  13. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/install/hapi.js +2 -2
  14. package/node_modules/@contrast/assess/lib/{session-configuration → configuration-analysis}/install/koa.js +3 -3
  15. package/node_modules/@contrast/assess/lib/dataflow/propagation/install/string/substring.js +1 -1
  16. package/node_modules/@contrast/assess/lib/dataflow/sources/handler.js +30 -26
  17. package/node_modules/@contrast/assess/lib/dataflow/sources/index.js +2 -0
  18. package/node_modules/@contrast/assess/lib/dataflow/sources/install/fastify-websocket.js +63 -0
  19. package/node_modules/@contrast/assess/lib/dataflow/sources/install/http.js +42 -38
  20. package/node_modules/@contrast/assess/lib/dataflow/sources/install/koa/index.js +1 -1
  21. package/node_modules/@contrast/assess/lib/dataflow/sources/install/koa/koa-bodyparsers.js +76 -48
  22. package/node_modules/@contrast/assess/lib/dataflow/sources/install/koa/koa-multer.js +1 -1
  23. package/node_modules/@contrast/assess/lib/dataflow/sources/install/koa/koa-routers.js +2 -2
  24. package/node_modules/@contrast/assess/lib/dataflow/sources/install/koa/{koa2.js → koa.js} +3 -3
  25. package/node_modules/@contrast/assess/lib/dataflow/sources/install/socket.io.js +80 -0
  26. package/node_modules/@contrast/assess/lib/get-source-context.js +10 -21
  27. package/node_modules/@contrast/assess/lib/index.d.ts +4 -3
  28. package/node_modules/@contrast/assess/lib/index.js +2 -2
  29. package/node_modules/@contrast/assess/lib/make-source-context.js +5 -10
  30. package/node_modules/@contrast/assess/lib/policy.js +400 -0
  31. package/node_modules/@contrast/assess/lib/response-scanning/handlers/index.js +10 -14
  32. package/node_modules/@contrast/assess/package.json +12 -12
  33. package/node_modules/@contrast/common/lib/constants.d.ts +12 -4
  34. package/node_modules/@contrast/common/lib/constants.js +16 -7
  35. package/node_modules/@contrast/common/lib/types.d.ts +5 -1
  36. package/node_modules/@contrast/common/package.json +1 -1
  37. package/node_modules/@contrast/config/lib/common.js +1 -0
  38. package/node_modules/@contrast/config/lib/options.js +14 -0
  39. package/node_modules/@contrast/config/package.json +3 -3
  40. package/node_modules/@contrast/core/package.json +5 -5
  41. package/node_modules/@contrast/deadzones/package.json +5 -5
  42. package/node_modules/@contrast/dep-hooks/lib/package-finder.d.ts +2 -2
  43. package/node_modules/@contrast/dep-hooks/lib/package-finder.js +3 -2
  44. package/node_modules/@contrast/dep-hooks/package.json +4 -4
  45. package/node_modules/@contrast/esm-hooks/README.md +2 -2
  46. package/node_modules/@contrast/esm-hooks/package.json +6 -6
  47. package/node_modules/@contrast/instrumentation/package.json +5 -5
  48. package/node_modules/@contrast/library-analysis/lib/install/library-reporting/dep.json +149 -149
  49. package/node_modules/@contrast/library-analysis/lib/install/library-reporting/index.js +2 -11
  50. package/node_modules/@contrast/library-analysis/lib/install/library-reporting/utils.js +2 -0
  51. package/node_modules/@contrast/library-analysis/lib/install/library-usage/index.js +3 -1
  52. package/node_modules/@contrast/library-analysis/lib/util.js +0 -2
  53. package/node_modules/@contrast/library-analysis/package.json +4 -4
  54. package/node_modules/@contrast/logger/package.json +3 -3
  55. package/node_modules/@contrast/metrics/package.json +6 -6
  56. package/node_modules/@contrast/patcher/package.json +2 -2
  57. package/node_modules/@contrast/protect/lib/error-handlers/index.js +1 -1
  58. package/node_modules/@contrast/protect/lib/error-handlers/install/{koa2.js → koa.js} +4 -4
  59. package/node_modules/@contrast/protect/lib/index.d.ts +1 -1
  60. package/node_modules/@contrast/protect/lib/input-analysis/handlers.js +1 -12
  61. package/node_modules/@contrast/protect/lib/input-analysis/index.js +2 -3
  62. package/node_modules/@contrast/protect/lib/input-analysis/install/koa-bodyparsers.js +92 -0
  63. package/node_modules/@contrast/protect/lib/input-analysis/install/{koa2.js → koa.js} +5 -5
  64. package/node_modules/@contrast/protect/package.json +11 -11
  65. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/application-activity/translations.js +6 -10
  66. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/routes-observed.js +4 -0
  67. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/index.d.ts +1 -1
  68. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/index.js +1 -1
  69. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/translations.d.ts +1 -1
  70. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/translations.js +22 -9
  71. package/node_modules/@contrast/reporter/lib/reporters/file.js +1 -1
  72. package/node_modules/@contrast/reporter/package.json +6 -6
  73. package/node_modules/@contrast/rewriter/package.json +5 -5
  74. package/node_modules/@contrast/route-coverage/lib/index.d.ts +0 -2
  75. package/node_modules/@contrast/route-coverage/lib/index.js +10 -1
  76. package/node_modules/@contrast/route-coverage/lib/install/express/express5.js +16 -1
  77. package/node_modules/@contrast/route-coverage/lib/install/fastify.js +25 -15
  78. package/node_modules/@contrast/route-coverage/lib/install/graphql.js +6 -1
  79. package/node_modules/@contrast/route-coverage/lib/install/koa.js +1 -1
  80. package/node_modules/@contrast/route-coverage/lib/install/socket.io.js +127 -0
  81. package/node_modules/@contrast/route-coverage/package.json +8 -8
  82. package/node_modules/@contrast/scopes/package.json +5 -5
  83. package/node_modules/@contrast/sec-obs/package.json +9 -9
  84. package/node_modules/@contrast/sources/lib/index.js +65 -22
  85. package/node_modules/@contrast/sources/lib/index.test.js +78 -33
  86. package/node_modules/@contrast/sources/lib/source-info.js +1 -10
  87. package/node_modules/@contrast/sources/package.json +3 -3
  88. package/node_modules/@contrast/telemetry/package.json +5 -5
  89. package/node_modules/@types/node/README.md +1 -1
  90. package/node_modules/@types/node/assert/strict.d.ts +105 -2
  91. package/node_modules/@types/node/assert.d.ts +154 -95
  92. package/node_modules/@types/node/buffer.buffer.d.ts +9 -0
  93. package/node_modules/@types/node/buffer.d.ts +8 -4
  94. package/node_modules/@types/node/child_process.d.ts +65 -42
  95. package/node_modules/@types/node/cluster.d.ts +4 -5
  96. package/node_modules/@types/node/crypto.d.ts +1173 -322
  97. package/node_modules/@types/node/dgram.d.ts +9 -8
  98. package/node_modules/@types/node/diagnostics_channel.d.ts +0 -2
  99. package/node_modules/@types/node/dns.d.ts +1 -1
  100. package/node_modules/@types/node/events.d.ts +80 -34
  101. package/node_modules/@types/node/fs/promises.d.ts +39 -21
  102. package/node_modules/@types/node/fs.d.ts +328 -87
  103. package/node_modules/@types/node/globals.d.ts +2 -0
  104. package/node_modules/@types/node/globals.typedarray.d.ts +19 -0
  105. package/node_modules/@types/node/http.d.ts +94 -30
  106. package/node_modules/@types/node/http2.d.ts +178 -52
  107. package/node_modules/@types/node/https.d.ts +91 -62
  108. package/node_modules/@types/node/index.d.ts +2 -0
  109. package/node_modules/@types/node/inspector.d.ts +24 -0
  110. package/node_modules/@types/node/inspector.generated.d.ts +181 -0
  111. package/node_modules/@types/node/net.d.ts +12 -11
  112. package/node_modules/@types/node/os.d.ts +14 -3
  113. package/node_modules/@types/node/package.json +3 -3
  114. package/node_modules/@types/node/perf_hooks.d.ts +6 -8
  115. package/node_modules/@types/node/process.d.ts +12 -23
  116. package/node_modules/@types/node/readline/promises.d.ts +1 -1
  117. package/node_modules/@types/node/sea.d.ts +9 -0
  118. package/node_modules/@types/node/sqlite.d.ts +119 -10
  119. package/node_modules/@types/node/stream/consumers.d.ts +2 -2
  120. package/node_modules/@types/node/stream/web.d.ts +6 -55
  121. package/node_modules/@types/node/stream.d.ts +38 -23
  122. package/node_modules/@types/node/string_decoder.d.ts +2 -2
  123. package/node_modules/@types/node/test.d.ts +31 -26
  124. package/node_modules/@types/node/tls.d.ts +90 -66
  125. package/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +10 -2
  126. package/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +16 -0
  127. package/node_modules/@types/node/ts5.6/index.d.ts +2 -0
  128. package/node_modules/@types/node/ts5.7/index.d.ts +2 -0
  129. package/node_modules/@types/node/url.d.ts +8 -3
  130. package/node_modules/@types/node/util.d.ts +17 -3
  131. package/node_modules/@types/node/v8.d.ts +38 -5
  132. package/node_modules/@types/node/vm.d.ts +169 -88
  133. package/node_modules/@types/node/wasi.d.ts +1 -1
  134. package/node_modules/@types/node/web-globals/crypto.d.ts +32 -0
  135. package/node_modules/@types/node/web-globals/events.d.ts +3 -0
  136. package/node_modules/@types/node/web-globals/streams.d.ts +22 -0
  137. package/node_modules/@types/node/worker_threads.d.ts +109 -48
  138. package/node_modules/@types/node/zlib.d.ts +31 -24
  139. package/node_modules/axios/CHANGELOG.md +403 -357
  140. package/node_modules/axios/README.md +80 -49
  141. package/node_modules/axios/dist/axios.js +121 -46
  142. package/node_modules/axios/dist/axios.js.map +1 -1
  143. package/node_modules/axios/dist/axios.min.js +2 -2
  144. package/node_modules/axios/dist/axios.min.js.map +1 -1
  145. package/node_modules/axios/dist/browser/axios.cjs +126 -57
  146. package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
  147. package/node_modules/axios/dist/esm/axios.js +126 -57
  148. package/node_modules/axios/dist/esm/axios.js.map +1 -1
  149. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  150. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  151. package/node_modules/axios/dist/node/axios.cjs +346 -97
  152. package/node_modules/axios/dist/node/axios.cjs.map +1 -1
  153. package/node_modules/axios/index.d.cts +4 -0
  154. package/node_modules/axios/index.d.ts +4 -0
  155. package/node_modules/axios/lib/adapters/adapters.js +85 -40
  156. package/node_modules/axios/lib/adapters/fetch.js +1 -1
  157. package/node_modules/axios/lib/adapters/http.js +220 -42
  158. package/node_modules/axios/lib/core/InterceptorManager.js +1 -1
  159. package/node_modules/axios/lib/core/mergeConfig.js +4 -4
  160. package/node_modules/axios/lib/env/data.js +1 -1
  161. package/node_modules/axios/lib/helpers/HttpStatusCode.js +6 -0
  162. package/node_modules/axios/lib/helpers/bind.js +7 -0
  163. package/node_modules/axios/lib/helpers/cookies.js +24 -13
  164. package/node_modules/axios/package.json +9 -4
  165. package/node_modules/detect-libc/lib/filesystem.js +1 -1
  166. package/node_modules/detect-libc/package.json +3 -1
  167. package/node_modules/node-abi/abi_registry.json +12 -2
  168. package/node_modules/node-abi/package.json +3 -6
  169. package/node_modules/semver/classes/range.js +1 -0
  170. package/node_modules/semver/classes/semver.js +19 -5
  171. package/node_modules/semver/internal/identifiers.js +4 -0
  172. package/node_modules/semver/package.json +3 -3
  173. package/node_modules/undici-types/agent.d.ts +1 -4
  174. package/node_modules/undici-types/client.d.ts +0 -2
  175. package/node_modules/undici-types/diagnostics-channel.d.ts +0 -1
  176. package/node_modules/undici-types/dispatcher.d.ts +0 -6
  177. package/node_modules/undici-types/errors.d.ts +5 -15
  178. package/node_modules/undici-types/eventsource.d.ts +6 -1
  179. package/node_modules/undici-types/h2c-client.d.ts +0 -2
  180. package/node_modules/undici-types/index.d.ts +6 -1
  181. package/node_modules/undici-types/interceptors.d.ts +5 -0
  182. package/node_modules/undici-types/mock-interceptor.d.ts +0 -1
  183. package/node_modules/undici-types/package.json +1 -1
  184. package/node_modules/undici-types/snapshot-agent.d.ts +109 -0
  185. package/node_modules/undici-types/webidl.d.ts +82 -21
  186. package/package.json +3 -3
  187. package/node_modules/@contrast/assess/lib/get-policy.js +0 -336
  188. package/node_modules/@contrast/protect/lib/input-analysis/install/koa-body5.js +0 -63
  189. package/node_modules/@contrast/protect/lib/input-analysis/install/koa-bodyparser4.js +0 -64
package/README.md CHANGED
@@ -61,7 +61,7 @@ node --import @contrast/agent app-main [app arguments]
61
61
 
62
62
  Notes:
63
63
  - `--import` should be used for Node.js LTS (Active and Maintenance) versions `>=18.19.0`
64
- - Node.js versions `>=20.0.0 <20.6.0` are not supported
64
+ - Node.js versions `>=20.0.0 <20.9.0` are not supported
65
65
 
66
66
  ### With end-of-life Node.js Versions
67
67
 
@@ -61,7 +61,7 @@ node --import @contrast/agent app-main [app arguments]
61
61
 
62
62
  Notes:
63
63
  - `--import` should be used for Node.js LTS (Active and Maintenance) versions `>=18.19.0`
64
- - Node.js versions `>=20.0.0 <20.6.0` are not supported
64
+ - Node.js versions `>=20.0.0 <20.9.0` are not supported
65
65
 
66
66
  ### With end-of-life Node.js Versions
67
67
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agent",
3
- "version": "5.45.1",
3
+ "version": "5.47.0",
4
4
  "description": "Assess and Protect agents for Node.js",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -22,21 +22,21 @@
22
22
  "main": "./lib/index.js",
23
23
  "engines": {
24
24
  "npm": ">=6.13.7 <7 || >= 8.3.1",
25
- "node": ">=18.7.0 <19 || >=20.6.0 <21 || >= 22.5.1 <23 || >= 24.0.1 <25"
25
+ "node": ">=18.7.0 <19 || >=20.9.0 <21 || >= 22.5.1 <23 || >= 24.0.1 <25"
26
26
  },
27
27
  "scripts": {
28
28
  "test": "bash ../scripts/test.sh"
29
29
  },
30
30
  "dependencies": {
31
- "@contrast/agentify": "1.57.0",
32
- "@contrast/architecture-components": "1.45.1",
33
- "@contrast/assess": "1.63.0",
34
- "@contrast/common": "1.37.0",
35
- "@contrast/core": "1.57.1",
36
- "@contrast/library-analysis": "1.47.1",
37
- "@contrast/protect": "1.68.0",
38
- "@contrast/route-coverage": "1.49.1",
39
- "@contrast/sec-obs": "1.1.1",
40
- "@contrast/telemetry": "1.32.1"
31
+ "@contrast/agentify": "1.59.0",
32
+ "@contrast/architecture-components": "1.47.0",
33
+ "@contrast/assess": "1.65.0",
34
+ "@contrast/common": "1.38.0",
35
+ "@contrast/core": "1.59.0",
36
+ "@contrast/library-analysis": "1.49.0",
37
+ "@contrast/protect": "1.70.0",
38
+ "@contrast/route-coverage": "1.51.0",
39
+ "@contrast/sec-obs": "1.3.0",
40
+ "@contrast/telemetry": "1.34.0"
41
41
  }
42
42
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/agentify",
3
- "version": "1.57.0",
3
+ "version": "1.59.0",
4
4
  "description": "Configures Contrast agent services and instrumentation within an application",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -20,22 +20,22 @@
20
20
  "test": "bash ../scripts/test.sh"
21
21
  },
22
22
  "dependencies": {
23
- "@contrast/common": "1.37.0",
24
- "@contrast/config": "1.52.1",
25
- "@contrast/core": "1.57.1",
26
- "@contrast/deadzones": "1.29.1",
27
- "@contrast/dep-hooks": "1.26.1",
28
- "@contrast/esm-hooks": "2.32.0",
23
+ "@contrast/common": "1.38.0",
24
+ "@contrast/config": "1.54.0",
25
+ "@contrast/core": "1.59.0",
26
+ "@contrast/deadzones": "1.31.0",
27
+ "@contrast/dep-hooks": "1.28.0",
28
+ "@contrast/esm-hooks": "2.34.0",
29
29
  "@contrast/find-package-json": "^1.1.0",
30
- "@contrast/instrumentation": "1.36.1",
31
- "@contrast/logger": "1.30.1",
32
- "@contrast/metrics": "1.34.1",
33
- "@contrast/patcher": "1.29.1",
30
+ "@contrast/instrumentation": "1.38.0",
31
+ "@contrast/logger": "1.32.0",
32
+ "@contrast/metrics": "1.36.0",
33
+ "@contrast/patcher": "1.31.0",
34
34
  "@contrast/perf": "1.4.0",
35
- "@contrast/reporter": "1.55.1",
36
- "@contrast/rewriter": "1.34.0",
37
- "@contrast/scopes": "1.27.1",
38
- "@contrast/sources": "1.3.1",
35
+ "@contrast/reporter": "1.57.0",
36
+ "@contrast/rewriter": "1.36.0",
37
+ "@contrast/scopes": "1.29.0",
38
+ "@contrast/sources": "1.5.0",
39
39
  "on-finished": "^2.4.1",
40
40
  "semver": "^7.6.0"
41
41
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/architecture-components",
3
- "version": "1.45.1",
3
+ "version": "1.47.0",
4
4
  "description": "Detects external systems being connected to by applications.",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -20,9 +20,9 @@
20
20
  "test": "bash ../scripts/test.sh"
21
21
  },
22
22
  "dependencies": {
23
- "@contrast/common": "1.37.0",
24
- "@contrast/dep-hooks": "1.26.1",
25
- "@contrast/logger": "1.30.1",
26
- "@contrast/patcher": "1.29.1"
23
+ "@contrast/common": "1.38.0",
24
+ "@contrast/dep-hooks": "1.28.0",
25
+ "@contrast/logger": "1.32.0",
26
+ "@contrast/patcher": "1.31.0"
27
27
  }
28
28
  }
@@ -15,5 +15,5 @@
15
15
  'use strict';
16
16
 
17
17
  module.exports = {
18
- patchType: 'session-configuration'
18
+ patchType: 'configuration'
19
19
  };
@@ -17,15 +17,15 @@
17
17
 
18
18
  const {
19
19
  Event,
20
- SessionConfigurationRule,
20
+ ConfigurationRule,
21
21
  isString,
22
22
  } = require('@contrast/common');
23
23
 
24
- const { HTTPONLY, SECURE_FLAG_MISSING } = SessionConfigurationRule;
24
+ const { HTTPONLY, SECURE_FLAG_MISSING, GRAPHQL_INTROSPECTION } = ConfigurationRule;
25
25
 
26
26
  module.exports = function (core) {
27
27
  const {
28
- assess: { sessionConfiguration },
28
+ assess: { configurationAnalysis },
29
29
  messages,
30
30
  } = core;
31
31
 
@@ -40,7 +40,7 @@ module.exports = function (core) {
40
40
  }
41
41
 
42
42
  /**
43
- * @param {SessionConfigurationRule} ruleId
43
+ * @param {ConfigurationRule} ruleId
44
44
  * @param {import('@contrast/assess').SourceContext} sourceContext
45
45
  * @returns {import('@contrast/assess').SessionRuleState}
46
46
  */
@@ -67,7 +67,7 @@ module.exports = function (core) {
67
67
  function handle(ruleId, sourceContext, cookie, sessionEvent) {
68
68
  const state = ensureState(ruleId, sourceContext);
69
69
 
70
- if (!sourceContext?.policy?.enabledRules?.has?.(ruleId) || state.reported) return;
70
+ if (sourceContext?.policy?.disabledRules?.has?.(ruleId) || state.reported) return;
71
71
 
72
72
  for (const value of ensureIterable(cookie)) {
73
73
  if (state.valuesAnalyzed.has(value)) continue;
@@ -76,7 +76,7 @@ module.exports = function (core) {
76
76
  if (!isVulnerable(ruleId, value)) continue;
77
77
 
78
78
  else {
79
- sessionConfiguration.reportFindings({
79
+ configurationAnalysis.reportFindings({
80
80
  ruleId,
81
81
  sinkEvent: sessionEvent,
82
82
  properties: {
@@ -89,17 +89,30 @@ module.exports = function (core) {
89
89
  }
90
90
  }
91
91
 
92
- sessionConfiguration.handleHttpOnly = function(sourceContext, cookie, sessionEvent) {
92
+ configurationAnalysis.handleHttpOnly = function(sourceContext, cookie, sessionEvent) {
93
93
  handle(HTTPONLY, sourceContext, cookie, sessionEvent);
94
94
  };
95
95
 
96
- sessionConfiguration.handleSecure = function (sourceContext, cookie, sessionEvent) {
96
+ configurationAnalysis.handleSecure = function (sourceContext, cookie, sessionEvent) {
97
97
  handle(SECURE_FLAG_MISSING, sourceContext, cookie, sessionEvent);
98
98
  };
99
99
 
100
- sessionConfiguration.reportFindings = function (finding) {
101
- messages.emit(Event.ASSESS_SESSION_CONFIGURATION_FINDING, finding);
100
+ configurationAnalysis.handleGraphqlIntrospection = function (sourceContext, sessionEvent, value) {
101
+ const ruleId = GRAPHQL_INTROSPECTION;
102
+ const state = ensureState(ruleId, sourceContext);
103
+ if (sourceContext?.policy?.disabledRules?.has?.(ruleId) || state.reported) return;
104
+
105
+ configurationAnalysis.reportFindings({
106
+ ruleId,
107
+ sinkEvent: sessionEvent,
108
+ evidence: value
109
+ });
110
+ state.reported = true;
111
+ };
112
+
113
+ configurationAnalysis.reportFindings = function (finding) {
114
+ messages.emit(Event.ASSESS_CONFIGURATION_FINDING, finding);
102
115
  };
103
116
 
104
- return sessionConfiguration;
117
+ return configurationAnalysis;
105
118
  };
@@ -18,17 +18,19 @@
18
18
  const { callChildComponentMethodsSync } = require('@contrast/common');
19
19
 
20
20
  module.exports = function(core) {
21
- const sessionConfiguration = core.assess.sessionConfiguration = {};
21
+ const configurationAnalysis = core.assess.configurationAnalysis = {};
22
22
 
23
23
  require('./handlers')(core);
24
+ require('./install/apollo-server')(core);
25
+ require('./install/graphql-yoga')(core);
24
26
  require('./install/express-session')(core);
25
27
  require('./install/fastify-cookie')(core);
26
28
  require('./install/hapi')(core);
27
29
  require('./install/koa')(core);
28
30
 
29
- sessionConfiguration.install = function() {
30
- callChildComponentMethodsSync(sessionConfiguration, 'install');
31
+ configurationAnalysis.install = function() {
32
+ callChildComponentMethodsSync(configurationAnalysis, 'install');
31
33
  };
32
34
 
33
- return sessionConfiguration;
35
+ return configurationAnalysis;
34
36
  };
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Copyright: 2025 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+ 'use strict';
16
+
17
+ const { patchType } = require('../common');
18
+
19
+ /**
20
+ * @param {{
21
+ * assess: import('@contrast/assess').Assess,
22
+ * scopes: import('@contrast/scopes').Scopes,
23
+ * }} core
24
+ */
25
+ module.exports = function (core) {
26
+ const {
27
+ assess: {
28
+ inspect, // TODO NODE-3455: remove
29
+ getSourceContext,
30
+ eventFactory: { createSessionEvent },
31
+ configurationAnalysis: {
32
+ handleGraphqlIntrospection
33
+ },
34
+ },
35
+ depHooks,
36
+ patcher,
37
+ } = core;
38
+
39
+ const apolloServer = core.assess.configurationAnalysis.apolloServer = {};
40
+
41
+ apolloServer.install = function () {
42
+ return depHooks.resolve({ name: '@apollo/server', version: '>=4', file: 'dist/cjs' }, (xport) => {
43
+ if (!xport.ApolloServer) return;
44
+ patcher.patch(xport, 'ApolloServer', {
45
+ name: '@apollo/server.ApolloServer',
46
+ patchType,
47
+ post(data) {
48
+ if (!data.args[0]?.introspection) return;
49
+
50
+ const options = { introspection: true };
51
+ const optionsString = inspect(options);
52
+ const sessionEvent = createSessionEvent({
53
+ args: [{
54
+ tracked: false,
55
+ value: optionsString,
56
+ }],
57
+ context: optionsString,
58
+ name: '@apollo/server',
59
+ moduleName: 'ApolloServer',
60
+ methodName: '',
61
+ object: {
62
+ tracked: false,
63
+ value: 'ApolloServer',
64
+ },
65
+ result: {
66
+ tracked: false,
67
+ },
68
+ source: 'P0',
69
+ stacktraceOpts: {
70
+ constructorOpt: data.hooked,
71
+ },
72
+ framework: 'graphql',
73
+ });
74
+
75
+ patcher.patch(data.result, 'executeHTTPGraphQLRequest', {
76
+ name: 'ApolloServer.executeHTTPGraphQLRequest',
77
+ patchType,
78
+ post(data) {
79
+ const sourceContext = getSourceContext();
80
+ if (!sourceContext) return;
81
+
82
+ handleGraphqlIntrospection(sourceContext, sessionEvent, optionsString);
83
+
84
+ }
85
+ });
86
+ }
87
+ });
88
+ });
89
+ };
90
+
91
+ return apolloServer;
92
+ };
@@ -29,7 +29,7 @@ module.exports = function (core) {
29
29
  inspect, // TODO NODE-3455: remove
30
30
  getSourceContext,
31
31
  eventFactory: { createSessionEvent },
32
- sessionConfiguration: {
32
+ configurationAnalysis: {
33
33
  handleHttpOnly,
34
34
  handleSecure,
35
35
  },
@@ -38,7 +38,7 @@ module.exports = function (core) {
38
38
  patcher,
39
39
  } = core;
40
40
 
41
- const expressSession = core.assess.sessionConfiguration.expressSession = {};
41
+ const expressSession = core.assess.configurationAnalysis.expressSession = {};
42
42
 
43
43
  expressSession.install = function () {
44
44
  return depHooks.resolve({ name: 'express-session', version: '<2' }, (session) => {
@@ -29,7 +29,7 @@ module.exports = function (core) {
29
29
  inspect, // TODO NODE-3455: remove
30
30
  getSourceContext,
31
31
  eventFactory: { createSessionEvent },
32
- sessionConfiguration: {
32
+ configurationAnalysis: {
33
33
  handleHttpOnly,
34
34
  handleSecure,
35
35
  },
@@ -38,7 +38,7 @@ module.exports = function (core) {
38
38
  patcher,
39
39
  } = core;
40
40
 
41
- return core.assess.sessionConfiguration.fastifyCookie = {
41
+ return core.assess.configurationAnalysis.fastifyCookie = {
42
42
  install () {
43
43
  depHooks.resolve({ name: '@fastify/cookie', version: '<12' }, (_export) => {
44
44
  const patched = patcher.patch(_export, {
@@ -0,0 +1,90 @@
1
+ /*
2
+ * Copyright: 2025 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+ 'use strict';
16
+
17
+ const { patchType } = require('../common');
18
+
19
+ /**
20
+ * @param {{
21
+ * assess: import('@contrast/assess').Assess,
22
+ * scopes: import('@contrast/scopes').Scopes,
23
+ * }} core
24
+ */
25
+ module.exports = function (core) {
26
+ const {
27
+ assess: {
28
+ inspect, // TODO NODE-3455: remove
29
+ getSourceContext,
30
+ eventFactory: { createSessionEvent },
31
+ configurationAnalysis: {
32
+ handleGraphqlIntrospection
33
+ },
34
+ },
35
+ depHooks,
36
+ patcher,
37
+ } = core;
38
+
39
+ const graphqlYoga = core.assess.configurationAnalysis.graphqlYoga = {};
40
+
41
+ graphqlYoga.install = function () {
42
+ return depHooks.resolve({ name: '@graphql-yoga/plugin-disable-introspection', version: '*', file: 'cjs' }, (xport) => patcher.patch(xport, 'useDisableIntrospection', {
43
+ name: '@graphql-yoga/plugin-disable-introspection.useDisableIntrospection',
44
+ patchType,
45
+ post(data) {
46
+ const options = data.args[0];
47
+ const optionsString = inspect(options);
48
+ patcher.patch(data.result, 'onValidate', {
49
+ name: 'onValidate',
50
+ patchType,
51
+ pre(data) {
52
+ patcher.patch(data.args[0], 'addValidationRule', {
53
+ name: 'addValidationRule',
54
+ patchType,
55
+ post(data) {
56
+ const sourceContext = getSourceContext();
57
+ if (!sourceContext) return;
58
+ const sessionEvent = createSessionEvent({
59
+ args: [{
60
+ tracked: false,
61
+ value: optionsString,
62
+ }],
63
+ context: optionsString,
64
+ name: '@graphql-yoga',
65
+ moduleName: 'plugin-disable-introspection',
66
+ methodName: 'addValidationRule',
67
+ object: {
68
+ tracked: false,
69
+ value: 'plugin-disable-introspection',
70
+ },
71
+ result: {
72
+ tracked: false,
73
+ },
74
+ source: 'P0',
75
+ stacktraceOpts: {
76
+ constructorOpt: data.hooked,
77
+ },
78
+ framework: 'graphql',
79
+ });
80
+ handleGraphqlIntrospection(sourceContext, sessionEvent, optionsString);
81
+ }
82
+ });
83
+ }
84
+ });
85
+ }
86
+ }));
87
+ };
88
+
89
+ return graphqlYoga;
90
+ };
@@ -21,7 +21,7 @@ module.exports = function (core) {
21
21
  assess: {
22
22
  inspect, // TODO NODE-3455: remove
23
23
  eventFactory: { createSessionEvent },
24
- sessionConfiguration: {
24
+ configurationAnalysis: {
25
25
  handleHttpOnly,
26
26
  handleSecure,
27
27
  },
@@ -31,7 +31,7 @@ module.exports = function (core) {
31
31
  scopes: { sources },
32
32
  } = core;
33
33
 
34
- const hapiSession = core.assess.sessionConfiguration.hapiSession = {};
34
+ const hapiSession = core.assess.configurationAnalysis.hapiSession = {};
35
35
 
36
36
  hapiSession.install = function () {
37
37
  return depHooks.resolve({ name: '@hapi/hapi', version: '>=18 <22' }, (hapi) => {
@@ -28,7 +28,7 @@ module.exports = function (core) {
28
28
  inspect, // TODO NODE-3455: remove
29
29
  getSourceContext,
30
30
  eventFactory: { createSessionEvent },
31
- sessionConfiguration: {
31
+ configurationAnalysis: {
32
32
  handleHttpOnly,
33
33
  handleSecure,
34
34
  },
@@ -37,9 +37,9 @@ module.exports = function (core) {
37
37
  patcher,
38
38
  } = core;
39
39
 
40
- return core.assess.sessionConfiguration.koa = {
40
+ return core.assess.configurationAnalysis.koa = {
41
41
  install () {
42
- depHooks.resolve({ name: 'koa', version: '>=2.3.0 <3' }, (Koa) => {
42
+ depHooks.resolve({ name: 'koa', version: '>=2.3.0 <4' }, (Koa) => {
43
43
  patcher.patch(Koa.prototype, 'use', {
44
44
  name: 'Koa.Application',
45
45
  patchType,
@@ -89,7 +89,7 @@ module.exports = function(core) {
89
89
  const event = createPropagationEvent({
90
90
  name,
91
91
  moduleName: 'String',
92
- methodName: 'prototype.substring',
92
+ methodName: `prototype.${method}`,
93
93
  get context() {
94
94
  return `'${objInfo.value}'.substring(${ArrayPrototypeJoin.call(args.map(a => a.value))})`;
95
95
  },
@@ -45,24 +45,19 @@ module.exports = Core.makeComponent({
45
45
  const logger = core.logger.child({ name: 'contrast:sources' });
46
46
 
47
47
  sources.createTags = function createTags({ inputType, fieldName = '', value, tagNames }) {
48
- if (!value?.length) {
49
- return null;
50
- }
48
+ if (!value?.length) return null;
51
49
 
52
50
  const stop = value.length - 1;
53
- const tags = {
54
- [DataflowTag.UNTRUSTED]: [0, stop]
55
- };
51
+ const tags = { [DataflowTag.UNTRUSTED]: [0, stop] };
56
52
 
57
- if (tagNames) {
58
- for (const tag of tagNames) {
53
+ if (tagNames)
54
+ for (const tag of tagNames)
59
55
  tags[tag] = [0, stop];
60
- }
61
- }
62
56
 
63
- if (inputType === InputType.HEADER && StringPrototypeToLowerCase.call(fieldName) === 'referer') {
64
- tags[DataflowTag.HEADER] = [0, stop];
65
- }
57
+ if (
58
+ inputType === InputType.HEADER &&
59
+ StringPrototypeToLowerCase.call(fieldName) === 'referer'
60
+ ) tags[DataflowTag.HEADER] = [0, stop];
66
61
 
67
62
  return tags;
68
63
  };
@@ -81,6 +76,7 @@ module.exports = Core.makeComponent({
81
76
  stacktraceOpts,
82
77
  data,
83
78
  sourceContext,
79
+ onEvent,
84
80
  }) {
85
81
  if (!data) return;
86
82
 
@@ -89,14 +85,7 @@ module.exports = Core.makeComponent({
89
85
  return null;
90
86
  }
91
87
 
92
- // url exclusion
93
- if (!sourceContext.policy) {
94
- return null;
95
- }
96
-
97
- if (!context) {
98
- context = inputType;
99
- }
88
+ if (!context) context = inputType;
100
89
 
101
90
  const { policy: requestPolicy } = sourceContext;
102
91
  const max = config.assess.max_context_source_events;
@@ -111,10 +100,13 @@ module.exports = Core.makeComponent({
111
100
  }
112
101
 
113
102
  function createEvent({ fieldName, pathName, value, excludedRules }) {
114
- const tagNames = Array.from(excludedRules).map((ruleId) => `excluded:${ruleId}`);
103
+ let tagNames;
104
+ if (excludedRules) {
105
+ tagNames = Array.from(excludedRules).map((ruleId) => `excluded:${ruleId}`);
106
+ }
115
107
  // create the stacktrace once per call to .handle()
116
108
  stack || (stack = sources.createStacktrace(stacktraceOpts));
117
- return eventFactory.createSourceEvent({
109
+ const eventData = {
118
110
  context: `${context}.${pathName}`,
119
111
  name,
120
112
  fieldName,
@@ -123,11 +115,19 @@ module.exports = Core.makeComponent({
123
115
  inputType,
124
116
  tags: sources.createTags({ inputType, fieldName, value, tagNames }),
125
117
  result: { tracked: true, value },
126
- });
118
+ };
119
+
120
+ const event = eventFactory.createSourceEvent(eventData);;
121
+ if (event && onEvent) onEvent(event, fieldName, pathName);
122
+
123
+ return event;
127
124
  }
128
125
 
129
126
  if (Buffer.isBuffer(data) && !tracker.getData(data)) {
130
- const { track, excludedRules } = requestPolicy.getInputPolicy(InputType.BODY);
127
+ const inputPolicy = requestPolicy.getInputPolicy(InputType.BODY);
128
+ const track = !!inputPolicy;
129
+ const excludedRules = inputPolicy?.constructor?.name == 'Set' ? inputPolicy : undefined;
130
+
131
131
  if (!track) {
132
132
  core.logger.debug({ inputType }, 'assess input exclusion disabled tracking');
133
133
  return;
@@ -135,6 +135,7 @@ module.exports = Core.makeComponent({
135
135
 
136
136
  const event = createEvent({ pathName: 'body', value: data, fieldName: '', excludedRules });
137
137
  if (event) {
138
+ if (onEvent) onEvent(event);
138
139
  tracker.track(data, event);
139
140
  }
140
141
 
@@ -149,7 +150,10 @@ module.exports = Core.makeComponent({
149
150
  return true;
150
151
  }
151
152
 
152
- const { track, excludedRules } = sourceContext.policy.getInputPolicy(inputType, fieldName);
153
+ const inputPolicy = sourceContext.policy.getInputPolicy(inputType, fieldName);
154
+ const track = !!inputPolicy;
155
+ const excludedRules = inputPolicy?.constructor?.name == 'Set' ? inputPolicy : undefined;
156
+
153
157
  if (!track) {
154
158
  core.logger.debug({ fieldName, inputType }, 'assess input exclusion disabling tracking');
155
159
  return;
@@ -29,12 +29,14 @@ module.exports = function (core) {
29
29
  require('./install/body-parser')(core);
30
30
  require('./install/busboy')(core);
31
31
  require('./install/cookie-parser1')(core);
32
+ core.initComponentSync(require('./install/fastify-websocket'));
32
33
  require('./install/formidable1')(core);
33
34
  require('./install/graphql-http')(core);
34
35
  require('./install/http')(core);
35
36
  require('./install/qs6')(core);
36
37
  require('./install/querystring')(core);
37
38
  require('./install/multer1')(core);
39
+ core.initComponentSync(require('./install/socket.io'));
38
40
 
39
41
  sources.install = function install() {
40
42
  callChildComponentMethodsSync(sources, 'install');