@contrast/assess 1.18.0 → 1.19.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 (47) hide show
  1. package/lib/constants.js +26 -0
  2. package/lib/crypto-analysis/common.js +20 -0
  3. package/lib/crypto-analysis/index.js +44 -0
  4. package/lib/crypto-analysis/install/crypto.js +151 -0
  5. package/lib/crypto-analysis/install/math.js +99 -0
  6. package/lib/dataflow/propagation/install/JSON/parse.js +12 -11
  7. package/lib/dataflow/propagation/install/JSON/stringify.js +1 -1
  8. package/lib/dataflow/propagation/install/ejs/escape-xml.js +2 -2
  9. package/lib/dataflow/propagation/install/ejs/index.js +1 -0
  10. package/lib/dataflow/propagation/install/ejs/template.js +77 -0
  11. package/lib/dataflow/propagation/install/util-format.js +9 -3
  12. package/lib/dataflow/sinks/install/child-process.js +20 -14
  13. package/lib/dataflow/sinks/install/eval.js +16 -14
  14. package/lib/dataflow/sinks/install/express/unvalidated-redirect.js +14 -8
  15. package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +12 -5
  16. package/lib/dataflow/sinks/install/fs.js +7 -7
  17. package/lib/dataflow/sinks/install/function.js +8 -12
  18. package/lib/dataflow/sinks/install/http/request.js +16 -8
  19. package/lib/dataflow/sinks/install/http/server-response.js +11 -2
  20. package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +15 -8
  21. package/lib/dataflow/sinks/install/libxmljs.js +15 -10
  22. package/lib/dataflow/sinks/install/marsdb.js +13 -8
  23. package/lib/dataflow/sinks/install/mongodb.js +25 -15
  24. package/lib/dataflow/sinks/install/mssql.js +20 -9
  25. package/lib/dataflow/sinks/install/mysql.js +15 -8
  26. package/lib/dataflow/sinks/install/node-serialize.js +15 -17
  27. package/lib/dataflow/sinks/install/postgres.js +17 -4
  28. package/lib/dataflow/sinks/install/sequelize.js +16 -9
  29. package/lib/dataflow/sinks/install/sqlite3.js +20 -7
  30. package/lib/dataflow/sinks/install/vm.js +19 -17
  31. package/lib/dataflow/sources/install/http.js +14 -42
  32. package/lib/dataflow/sources/install/koa/index.js +1 -0
  33. package/lib/dataflow/sources/install/koa/koa-multer.js +102 -0
  34. package/lib/dataflow/sources/install/multer1.js +25 -51
  35. package/lib/dataflow/sources/install/querystring.js +1 -4
  36. package/lib/event-factory.js +47 -0
  37. package/lib/get-policy.js +68 -0
  38. package/lib/get-source-context.js +62 -0
  39. package/lib/index.d.ts +50 -0
  40. package/lib/index.js +20 -19
  41. package/lib/make-source-context.js +74 -0
  42. package/lib/response-scanning/handlers/index.js +55 -28
  43. package/lib/response-scanning/install/http.js +13 -7
  44. package/lib/rule-scopes.js +48 -0
  45. package/lib/session-configuration/handlers.js +4 -3
  46. package/lib/session-configuration/install/express-session.js +8 -2
  47. package/package.json +2 -2
@@ -17,6 +17,7 @@
17
17
 
18
18
  const util = require('util');
19
19
  const {
20
+ Rule: { UNVALIDATED_REDIRECT: ruleId },
20
21
  DataflowTag: {
21
22
  UNTRUSTED,
22
23
  CUSTOM_ENCODED,
@@ -27,18 +28,25 @@ const {
27
28
  },
28
29
  isString
29
30
  } = require('@contrast/common');
30
- const { patchType, filterSafeTags } = require('../../common');
31
+ const { InstrumentationType: { RULE } } = require('../../../../constants');
31
32
  const { createSubsetTags } = require('../../../tag-utils');
33
+ const { patchType, filterSafeTags } = require('../../common');
32
34
 
33
- const ruleId = 'unvalidated-redirect';
34
-
35
+ /**
36
+ * @param {{
37
+ * assess: import('@contrast/assess').Assess,
38
+ * config: import('@contrast/config').Config,
39
+ * logger: import('@contrast/logger').Logger,
40
+ * }} core
41
+ * @returns {import('@contrast/common').Installable}
42
+ */
35
43
  module.exports = function(core) {
36
44
  const {
37
45
  depHooks,
38
46
  patcher,
39
47
  config,
40
- scopes: { sources },
41
48
  assess: {
49
+ getSourceContext,
42
50
  eventFactory: { createSinkEvent },
43
51
  dataflow: {
44
52
  tracker,
@@ -46,9 +54,8 @@ module.exports = function(core) {
46
54
  },
47
55
  },
48
56
  } = core;
49
- const unvalidatedRedirect =
50
- (core.assess.dataflow.sinks.express.unvalidatedRedirect = {});
51
57
 
58
+ const unvalidatedRedirect = core.assess.dataflow.sinks.express.unvalidatedRedirect = {};
52
59
  const inspect = patcher.unwrap(util.inspect);
53
60
 
54
61
  const safeTags = [
@@ -66,8 +73,7 @@ module.exports = function(core) {
66
73
  name: 'Express.Response.location',
67
74
  patchType,
68
75
  pre: (data) => {
69
- const assessStore = sources.getStore()?.assess;
70
- if (!assessStore) return;
76
+ if (!getSourceContext(RULE, ruleId)) return;
71
77
 
72
78
  let [url] = data.args;
73
79
  if (url === 'back') {
@@ -17,6 +17,7 @@
17
17
 
18
18
  const util = require('util');
19
19
  const {
20
+ Rule: { UNVALIDATED_REDIRECT: ruleId },
20
21
  DataflowTag: {
21
22
  UNTRUSTED,
22
23
  CUSTOM_ENCODED,
@@ -27,11 +28,10 @@ const {
27
28
  },
28
29
  isString
29
30
  } = require('@contrast/common');
31
+ const { InstrumentationType: { RULE } } = require('../../../../constants');
30
32
  const { createSubsetTags } = require('../../../tag-utils');
31
33
  const { filterSafeTags, patchType } = require('../../common');
32
34
 
33
- const ruleId = 'unvalidated-redirect';
34
-
35
35
  const getURLArgument = (args) => {
36
36
  if (!Array.isArray(args)) {
37
37
  return { index: null, url: undefined };
@@ -51,13 +51,21 @@ const getURLArgument = (args) => {
51
51
  };
52
52
  };
53
53
 
54
+ /**
55
+ *
56
+ * @param {{
57
+ * assess: import('@contrast/assess').Assess,
58
+ * config: import('@contrast/config').Config,
59
+ * }} core
60
+ * @returns {import('@contrast/common').Installable}
61
+ */
54
62
  module.exports = function(core) {
55
63
  const {
56
64
  config,
57
65
  depHooks,
58
66
  patcher,
59
- scopes: { sources },
60
67
  assess: {
68
+ getSourceContext,
61
69
  eventFactory: { createSinkEvent },
62
70
  dataflow: {
63
71
  tracker,
@@ -85,8 +93,7 @@ module.exports = function(core) {
85
93
  name,
86
94
  patchType,
87
95
  post(data) {
88
- const assessStore = sources.getStore()?.assess;
89
- if (!assessStore) return;
96
+ if (!getSourceContext(RULE, ruleId)) return;
90
97
 
91
98
  const { url, index: valueIndex } = getURLArgument(data.args);
92
99
  if (!url || !isString(url)) return;
@@ -16,9 +16,6 @@
16
16
  'use strict';
17
17
  const { patchType } = require('../common');
18
18
  const {
19
- FS_METHODS,
20
- Rule,
21
- isString,
22
19
  DataflowTag: {
23
20
  URL_ENCODED,
24
21
  LIMITED_CHARS,
@@ -26,16 +23,20 @@ const {
26
23
  SAFE_PATH,
27
24
  UNTRUSTED,
28
25
  },
26
+ FS_METHODS,
27
+ Rule: { PATH_TRAVERSAL: ruleId },
29
28
  inspect,
29
+ isString,
30
30
  join,
31
31
  } = require('@contrast/common');
32
+ const { InstrumentationType: { RULE } } = require('../../../constants');
32
33
 
33
34
  module.exports = function(core) {
34
35
  const {
35
36
  depHooks,
36
37
  patcher,
37
- scopes: { instrumentation, sources },
38
38
  assess: {
39
+ getSourceContext,
39
40
  eventFactory: { createSinkEvent },
40
41
  dataflow: {
41
42
  tracker,
@@ -61,8 +62,7 @@ module.exports = function(core) {
61
62
 
62
63
  const pre = (name, method, moduleName = 'fs', fullMethodName = '') => (data) => {
63
64
  const { name: methodName, indices } = method;
64
- const store = sources.getStore()?.assess;
65
- if (!store || instrumentation.isLocked()) return;
65
+ if (!getSourceContext(RULE, ruleId)) return;
66
66
 
67
67
  const values = getValues(indices, data.args);
68
68
  if (!values.length) return;
@@ -105,7 +105,7 @@ module.exports = function(core) {
105
105
 
106
106
  if (event) {
107
107
  reportFindings({
108
- ruleId: Rule.PATH_TRAVERSAL,
108
+ ruleId,
109
109
  sinkEvent: event,
110
110
  });
111
111
  }
@@ -27,8 +27,9 @@ const {
27
27
  CUSTOM_VALIDATED,
28
28
  LIMITED_CHARS,
29
29
  },
30
- Rule: { UNSAFE_CODE_EXECUTION }
30
+ Rule: { UNSAFE_CODE_EXECUTION: ruleId }
31
31
  } = require('@contrast/common');
32
+ const { InstrumentationType: { RULE } } = require('../../../constants');
32
33
  const { patchType, filterSafeTags } = require('../common');
33
34
 
34
35
  const safeTags = [
@@ -44,8 +45,8 @@ module.exports = function (core) {
44
45
  config,
45
46
  logger,
46
47
  patcher,
47
- scopes: { sources, instrumentation },
48
48
  assess: {
49
+ getSourceContext,
49
50
  eventFactory: { createSinkEvent },
50
51
  dataflow: {
51
52
  tracker,
@@ -65,15 +66,10 @@ module.exports = function (core) {
65
66
  name: 'global.ContrastMethods.Function',
66
67
  patchType,
67
68
  pre({ args: origArgs, hooked, orig, name }) {
68
- const store = sources.getStore()?.assess;
69
+ if (!getSourceContext(RULE, ruleId)) return;
70
+
69
71
  const fnBody = origArgs[origArgs.length - 1];
70
- if (
71
- !store ||
72
- instrumentation.isLocked() ||
73
- !fnBody ||
74
- !isString(fnBody)
75
- )
76
- return;
72
+ if (!fnBody || !isString(fnBody)) return;
77
73
 
78
74
  const strInfo = tracker.getData(fnBody);
79
75
 
@@ -90,7 +86,7 @@ module.exports = function (core) {
90
86
 
91
87
  reportSafePositive({
92
88
  name,
93
- ruleId: UNSAFE_CODE_EXECUTION,
89
+ ruleId,
94
90
  safeTags: foundSafeTags,
95
91
  strInfo: safeStrInfo,
96
92
  });
@@ -142,7 +138,7 @@ module.exports = function (core) {
142
138
 
143
139
  if (event) {
144
140
  reportFindings({
145
- ruleId: UNSAFE_CODE_EXECUTION,
141
+ ruleId,
146
142
  sinkEvent: event,
147
143
  });
148
144
  }
@@ -15,6 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const Url = require('url');
18
19
  const {
19
20
  inspect,
20
21
  isString,
@@ -25,19 +26,27 @@ const {
25
26
  CUSTOM_VALIDATED_SSRF,
26
27
  CUSTOM_VALIDATED,
27
28
  LIMITED_CHARS
28
- }
29
+ },
30
+ Rule: { SSRF: ruleId },
29
31
  } = require('@contrast/common');
30
- const Url = require('url');
31
- const trustedLibs = [/^(?!.*(newrelic)).*http.*$/];
32
- const { patchType } = require('../../common');
32
+ const { InstrumentationType: { RULE } } = require('../../../../constants');
33
33
  const { createAppendTags } = require('../../../tag-utils');
34
+ const { patchType } = require('../../common');
35
+
36
+ const trustedLibs = [/^(?!.*(newrelic)).*http.*$/];
34
37
 
38
+ /**
39
+ * @param {{
40
+ * assess: import('@contrast/assess').Assess,
41
+ * }} core
42
+ * @returns {import('@contrast/common').Installable}
43
+ */
35
44
  module.exports = function(core) {
36
45
  const {
37
46
  depHooks,
38
47
  patcher,
39
- scopes: { sources },
40
48
  assess: {
49
+ getSourceContext,
41
50
  eventFactory: { createSinkEvent },
42
51
  dataflow: {
43
52
  tracker,
@@ -92,8 +101,7 @@ module.exports = function(core) {
92
101
  name,
93
102
  patchType,
94
103
  pre(data) {
95
- const sourceContext = sources.getStore()?.assess;
96
- if (!sourceContext) return;
104
+ if (!getSourceContext(RULE, ruleId)) return;
97
105
 
98
106
  const [req] = data.args;
99
107
  if (!req) return;
@@ -136,7 +144,7 @@ module.exports = function(core) {
136
144
 
137
145
  if (event) {
138
146
  reportFindings({
139
- ruleId: 'ssrf',
147
+ ruleId,
140
148
  sinkEvent: event
141
149
  });
142
150
  }
@@ -31,15 +31,24 @@ const {
31
31
  },
32
32
  Rule: { REFLECTED_XSS: ruleId },
33
33
  } = require('@contrast/common');
34
+ const { InstrumentationType: { RULE } } = require('../../../../constants');
35
+
34
36
  const { patchType, filterSafeTags } = require('../../common');
35
37
 
38
+ /**
39
+ * @param {{
40
+ * assess: import('@contrast/assess').Assess,
41
+ * config: import('@contrast/config').Config,
42
+ * }} core
43
+ * @returns {import('@contrast/common').Installable}
44
+ */
36
45
  module.exports = function(core) {
37
46
  const {
38
47
  config,
39
48
  depHooks,
40
49
  patcher,
41
- scopes: { sources },
42
50
  assess: {
51
+ getSourceContext,
43
52
  eventFactory: { createSinkEvent },
44
53
  dataflow: {
45
54
  tracker,
@@ -68,7 +77,7 @@ module.exports = function(core) {
68
77
  ];
69
78
 
70
79
  const preHook = (name, method) => (data) => {
71
- const sourceContext = sources.getStore()?.assess;
80
+ const sourceContext = getSourceContext(RULE, ruleId);
72
81
  if (!sourceContext) return;
73
82
 
74
83
  const payload = data.args[0];
@@ -25,20 +25,29 @@ const {
25
25
  LIMITED_CHARS,
26
26
  URL_ENCODED,
27
27
  },
28
+ Rule: { UNVALIDATED_REDIRECT: ruleId },
28
29
  isString
29
30
  } = require('@contrast/common');
31
+ const { InstrumentationType: { RULE } } = require('../../../../constants');
30
32
  const { createSubsetTags } = require('../../../tag-utils');
31
33
  const { filterSafeTags, patchType } = require('../../common');
32
34
 
33
- const ruleId = 'unvalidated-redirect';
34
-
35
+ /**
36
+ * @param {{
37
+ * assess: import('@contrast/assess').Assess,
38
+ * config: import('@contrast/config').Config,
39
+ * logger: import('@contrast/logger').Logger,
40
+ * messages: import('@contrast/common').Messages,
41
+ * }} core
42
+ * @returns {import('@contrast/common').Installable}
43
+ */
35
44
  module.exports = function(core) {
36
45
  const {
37
46
  depHooks,
38
47
  patcher,
39
48
  config,
40
- scopes: { sources },
41
49
  assess: {
50
+ getSourceContext,
42
51
  eventFactory: { createSinkEvent },
43
52
  dataflow: {
44
53
  tracker,
@@ -46,11 +55,8 @@ module.exports = function(core) {
46
55
  },
47
56
  },
48
57
  } = core;
49
- const unvalidatedRedirect =
50
- (core.assess.dataflow.sinks.koa.unvalidatedRedirect = {});
51
58
 
52
59
  const inspect = patcher.unwrap(util.inspect);
53
-
54
60
  const safeTags = [
55
61
  CUSTOM_ENCODED,
56
62
  CUSTOM_VALIDATED,
@@ -59,6 +65,8 @@ module.exports = function(core) {
59
65
  URL_ENCODED,
60
66
  ];
61
67
 
68
+ const unvalidatedRedirect = core.assess.dataflow.sinks.koa.unvalidatedRedirect = {};
69
+
62
70
  unvalidatedRedirect.install = function() {
63
71
  depHooks.resolve({ name: 'koa', file: 'lib/response', version: '<2.9.0' }, (Response) => {
64
72
  const name = 'Koa.Response.redirect';
@@ -66,8 +74,7 @@ module.exports = function(core) {
66
74
  name,
67
75
  patchType,
68
76
  pre(data) {
69
- const assessStore = sources.getStore()?.assess;
70
- if (!assessStore) return;
77
+ if (!getSourceContext(RULE, ruleId)) return;
71
78
 
72
79
  let isBackRoute = false;
73
80
  let [url] = data.args;
@@ -15,9 +15,8 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { patchType } = require('../common');
19
18
  const {
20
- Rule: { XXE },
19
+ Rule: { XXE: ruleId },
21
20
  isString,
22
21
  DataflowTag: {
23
22
  UNTRUSTED,
@@ -26,18 +25,29 @@ const {
26
25
  },
27
26
  inspect
28
27
  } = require('@contrast/common');
28
+ const { InstrumentationType: { RULE } } = require('../../../constants');
29
+ const { patchType } = require('../common');
29
30
 
30
31
  const safeTags = [
31
32
  LIMITED_CHARS,
32
33
  ALPHANUM_SPACE_HYPHEN
33
34
  ];
34
35
 
36
+ /**
37
+ * @param {{
38
+ * assess: import('@contrast/assess').Assess,
39
+ * config: import('@contrast/config').Config,
40
+ * logger: import('@contrast/logger').Logger,
41
+ * messages: import('@contrast/common').Messages,
42
+ * }} core
43
+ * @returns {import('@contrast/common').Installable}
44
+ */
35
45
  module.exports = function(core) {
36
46
  const {
37
47
  depHooks,
38
48
  patcher,
39
- scopes: { sources, instrumentation },
40
49
  assess: {
50
+ getSourceContext,
41
51
  eventFactory: { createSinkEvent },
42
52
  dataflow: {
43
53
  tracker,
@@ -60,12 +70,7 @@ module.exports = function(core) {
60
70
  name: `${moduleName}.${method}`,
61
71
  patchType,
62
72
  pre(data) {
63
- const store = sources.getStore()?.assess;
64
- if (
65
- !store ||
66
- !data.args[0] ||
67
- instrumentation.isLocked()
68
- ) return;
73
+ if (!getSourceContext(RULE, ruleId) || !data.args[0]) return;
69
74
 
70
75
  const [xmlString, opts] = data.args;
71
76
 
@@ -104,7 +109,7 @@ module.exports = function(core) {
104
109
 
105
110
  if (event) {
106
111
  reportFindings({
107
- ruleId: XXE,
112
+ ruleId,
108
113
  sinkEvent: event,
109
114
  });
110
115
  }
@@ -15,10 +15,9 @@
15
15
  'use strict';
16
16
 
17
17
  const util = require('util');
18
- const { patchType } = require('../common');
19
18
  const {
20
19
  traverseValues,
21
- Rule,
20
+ Rule: { NOSQL_INJECTION_MONGO: ruleId },
22
21
  DataflowTag: {
23
22
  ALPHANUM_SPACE_HYPHEN,
24
23
  LIMITED_CHARS,
@@ -27,6 +26,8 @@ const {
27
26
  CUSTOM_VALIDATED_NOSQL_INJECTION,
28
27
  },
29
28
  } = require('@contrast/common');
29
+ const { InstrumentationType: { RULE } } = require('../../../constants');
30
+ const { patchType } = require('../common');
30
31
 
31
32
  const collectionMethods = ['find', 'findOne', 'update', 'remove'];
32
33
  const querySafeTags = [
@@ -36,13 +37,20 @@ const querySafeTags = [
36
37
  CUSTOM_VALIDATED_NOSQL_INJECTION,
37
38
  ];
38
39
 
40
+ /**
41
+ * @param {{
42
+ * assess: import('@contrast/assess').Assess,
43
+ * logger: import('@contrast/logger').Logger,
44
+ * }} core
45
+ * @returns {import('@contrast/common').Installable}
46
+ */
39
47
  module.exports = function(core) {
40
48
  const {
41
49
  depHooks,
42
50
  logger,
43
51
  patcher,
44
- scopes: { sources, instrumentation },
45
52
  assess: {
53
+ getSourceContext,
46
54
  eventFactory: { createSinkEvent },
47
55
  dataflow: {
48
56
  tracker,
@@ -82,10 +90,7 @@ module.exports = function(core) {
82
90
  name,
83
91
  patchType,
84
92
  around(next, data) {
85
- const sourceCtx = sources.getStore()?.assess;
86
- if (!sourceCtx || instrumentation.isLocked()) {
87
- return next();
88
- }
93
+ if (!getSourceContext(RULE, ruleId)) return next();
89
94
 
90
95
  const argIdx = 0;
91
96
  const result = getVulnerabilityInfo(data.args[argIdx]);
@@ -120,7 +125,7 @@ module.exports = function(core) {
120
125
  });
121
126
 
122
127
  if (sinkEvent) {
123
- reportFindings({ ruleId: Rule.NOSQL_INJECTION_MONGO, sinkEvent });
128
+ reportFindings({ ruleId, sinkEvent });
124
129
  }
125
130
 
126
131
  return next();
@@ -24,12 +24,13 @@ const {
24
24
  LIMITED_CHARS,
25
25
  STRING_TYPE_CHECKED,
26
26
  },
27
- Rule: { NOSQL_INJECTION_MONGO },
27
+ Rule: { NOSQL_INJECTION_MONGO: ruleId },
28
28
  isNonEmptyObject,
29
29
  traverseValues,
30
30
  isString,
31
31
  inspect
32
32
  } = require('@contrast/common');
33
+ const { InstrumentationType: { RULE } } = require('../../../constants');
33
34
  const utils = require('../../tag-utils');
34
35
  const { patchType, filterSafeTags } = require('../common');
35
36
 
@@ -66,19 +67,28 @@ const querySafeTags = [
66
67
  STRING_TYPE_CHECKED,
67
68
  ];
68
69
 
70
+ /**
71
+ *
72
+ * @param {{
73
+ * assess: import('@contrast/assess').Assess,
74
+ * config: import('@contrast/config').Config,
75
+ * }} core
76
+ * @returns {import('@contrast/common').Installable}
77
+ */
69
78
  module.exports = function(core) {
70
79
  const {
71
80
  config,
72
81
  depHooks,
73
82
  logger,
74
83
  patcher,
75
- scopes: { sources, instrumentation },
76
84
  assess: {
85
+ getSourceContext,
77
86
  eventFactory: { createSinkEvent },
78
87
  dataflow: {
79
88
  tracker,
80
- sinks: { isVulnerable, runInActiveSink, isLocked, reportFindings, reportSafePositive }
81
- }
89
+ sinks: { isVulnerable, reportFindings, reportSafePositive }
90
+ },
91
+ ruleScopes,
82
92
  }
83
93
  } = core;
84
94
 
@@ -228,17 +238,13 @@ module.exports = function(core) {
228
238
  function createAroundHook(entity, name, method, getInfoMethod, vulnerableArgIdxs) {
229
239
  const argsIdxsToCheck = vulnerableArgIdxs || [0];
230
240
  return function(next, data) {
231
- const { obj, args: origArgs } = data;
232
- const sourceCtx = sources.getStore()?.assess;
233
-
234
- if (isLocked(NOSQL_INJECTION_MONGO) || instrumentation.isLocked() || !sourceCtx) {
235
- return next();
236
- }
241
+ if (!getSourceContext(RULE, ruleId)) return next();
237
242
 
243
+ const { obj, args: origArgs } = data;
244
+ const safeReports = [];
238
245
  let vulnInfo;
239
246
  let reportSafe;
240
247
  let vulnArgIdx;
241
- const safeReports = [];
242
248
 
243
249
  try {
244
250
  for (const argIdx of argsIdxsToCheck) {
@@ -272,13 +278,15 @@ module.exports = function(core) {
272
278
 
273
279
  reportSafePositive({
274
280
  name,
275
- ruleId: NOSQL_INJECTION_MONGO,
281
+ ruleId,
276
282
  safeTags,
277
283
  strInfo: strInfo.length === 1 ? strInfo[0] : strInfo
278
284
  });
279
285
  }
280
286
 
281
- return methodsWithNestedCalls.includes(method) ? runInActiveSink(NOSQL_INJECTION_MONGO, async () => await next()) : next();
287
+ return methodsWithNestedCalls.includes(method)
288
+ ? ruleScopes.run(ruleId, async () => await next())
289
+ : next();
282
290
  }
283
291
 
284
292
  const { path, strInfo } = vulnInfo;
@@ -313,13 +321,15 @@ module.exports = function(core) {
313
321
  });
314
322
 
315
323
  if (sinkEvent) {
316
- reportFindings({ ruleId: NOSQL_INJECTION_MONGO, sinkEvent });
324
+ reportFindings({ ruleId, sinkEvent });
317
325
  }
318
326
  } catch (err) {
319
327
  core.logger.error({ name, err }, 'assess sink analysis failed');
320
328
  }
321
329
 
322
- return methodsWithNestedCalls.includes(method) ? runInActiveSink(NOSQL_INJECTION_MONGO, async () => await next()) : next();
330
+ return methodsWithNestedCalls.includes(method)
331
+ ? ruleScopes.run(ruleId, async () => await next())
332
+ : next();
323
333
  };
324
334
  }
325
335
 
@@ -16,10 +16,17 @@
16
16
  'use strict';
17
17
 
18
18
  const {
19
- DataflowTag: { UNTRUSTED, SQL_ENCODED, LIMITED_CHARS, CUSTOM_VALIDATED, CUSTOM_ENCODED },
20
- Rule: { SQL_INJECTION },
19
+ DataflowTag: {
20
+ CUSTOM_VALIDATED,
21
+ CUSTOM_ENCODED,
22
+ LIMITED_CHARS,
23
+ SQL_ENCODED,
24
+ UNTRUSTED,
25
+ },
26
+ Rule: { SQL_INJECTION: ruleId },
21
27
  isString
22
28
  } = require('@contrast/common');
29
+ const { InstrumentationType: { RULE } } = require('../../../constants');
23
30
  const { createModuleLabel } = require('../../propagation/common');
24
31
  const { patchType, filterSafeTags } = require('../common');
25
32
 
@@ -30,15 +37,20 @@ const safeTags = [
30
37
  CUSTOM_ENCODED,
31
38
  ];
32
39
 
33
- const ruleId = SQL_INJECTION;
34
-
40
+ /**
41
+ * @param {{
42
+ * assess: import('@contrast/assess').Assess,
43
+ * config: import('@contrast/config').Config,
44
+ * }} core
45
+ * @returns {import('@contrast/common').Installable}
46
+ */
35
47
  module.exports = function(core) {
36
48
  const {
37
49
  depHooks,
38
50
  patcher,
39
51
  config,
40
- scopes: { sources },
41
52
  assess: {
53
+ getSourceContext,
42
54
  eventFactory: { createSinkEvent },
43
55
  dataflow: {
44
56
  tracker,
@@ -48,12 +60,11 @@ module.exports = function(core) {
48
60
  } = core;
49
61
 
50
62
  const pre = (name, method, obj, version) => (data) => {
51
- const store = sources.getStore()?.assess;
52
63
  if (
53
- !store ||
64
+ !getSourceContext(RULE, ruleId) ||
54
65
  !data.args[0] ||
55
66
  !isString(data.args[0]) ||
56
- isLocked(SQL_INJECTION)
67
+ isLocked(ruleId)
57
68
  ) return;
58
69
 
59
70
  const strInfo = tracker.getData(data.args[0]);
@@ -86,7 +97,7 @@ module.exports = function(core) {
86
97
 
87
98
  if (event) {
88
99
  reportFindings({
89
- ruleId: SQL_INJECTION,
100
+ ruleId,
90
101
  sinkEvent: event,
91
102
  });
92
103
  }