@contrast/assess 1.17.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 (53) 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/index.js +2 -1
  7. package/lib/dataflow/propagation/install/JSON/parse.js +12 -11
  8. package/lib/dataflow/propagation/install/JSON/stringify.js +1 -1
  9. package/lib/dataflow/propagation/install/array-prototype-join.js +1 -1
  10. package/lib/dataflow/propagation/install/ejs/escape-xml.js +2 -2
  11. package/lib/dataflow/propagation/install/ejs/index.js +1 -0
  12. package/lib/dataflow/propagation/install/ejs/template.js +77 -0
  13. package/lib/dataflow/propagation/install/sequelize/index.js +31 -0
  14. package/lib/dataflow/propagation/install/sequelize/query-generator.js +90 -0
  15. package/lib/dataflow/propagation/install/{sequelize.js → sequelize/sql-string.js} +3 -3
  16. package/lib/dataflow/propagation/install/util-format.js +126 -0
  17. package/lib/dataflow/sinks/index.js +1 -0
  18. package/lib/dataflow/sinks/install/child-process.js +20 -14
  19. package/lib/dataflow/sinks/install/eval.js +16 -14
  20. package/lib/dataflow/sinks/install/express/unvalidated-redirect.js +14 -8
  21. package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +12 -5
  22. package/lib/dataflow/sinks/install/fs.js +7 -7
  23. package/lib/dataflow/sinks/install/function.js +8 -12
  24. package/lib/dataflow/sinks/install/http/request.js +16 -8
  25. package/lib/dataflow/sinks/install/http/server-response.js +11 -2
  26. package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +15 -8
  27. package/lib/dataflow/sinks/install/libxmljs.js +15 -10
  28. package/lib/dataflow/sinks/install/marsdb.js +13 -8
  29. package/lib/dataflow/sinks/install/mongodb.js +25 -15
  30. package/lib/dataflow/sinks/install/mssql.js +20 -9
  31. package/lib/dataflow/sinks/install/mysql.js +15 -8
  32. package/lib/dataflow/sinks/install/node-serialize.js +101 -0
  33. package/lib/dataflow/sinks/install/postgres.js +17 -4
  34. package/lib/dataflow/sinks/install/sequelize.js +16 -9
  35. package/lib/dataflow/sinks/install/sqlite3.js +20 -7
  36. package/lib/dataflow/sinks/install/vm.js +19 -17
  37. package/lib/dataflow/sources/install/http.js +14 -42
  38. package/lib/dataflow/sources/install/koa/index.js +1 -0
  39. package/lib/dataflow/sources/install/koa/koa-multer.js +102 -0
  40. package/lib/dataflow/sources/install/multer1.js +25 -51
  41. package/lib/dataflow/sources/install/querystring.js +1 -4
  42. package/lib/event-factory.js +47 -0
  43. package/lib/get-policy.js +68 -0
  44. package/lib/get-source-context.js +62 -0
  45. package/lib/index.d.ts +50 -0
  46. package/lib/index.js +20 -19
  47. package/lib/make-source-context.js +74 -0
  48. package/lib/response-scanning/handlers/index.js +55 -28
  49. package/lib/response-scanning/install/http.js +13 -7
  50. package/lib/rule-scopes.js +48 -0
  51. package/lib/session-configuration/handlers.js +4 -3
  52. package/lib/session-configuration/install/express-session.js +8 -2
  53. package/package.json +2 -2
@@ -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
  }
@@ -17,8 +17,7 @@
17
17
 
18
18
  const { patchType } = require('../common');
19
19
  const {
20
- Rule: { SQL_INJECTION },
21
- isString,
20
+ Rule: { SQL_INJECTION: ruleId },
22
21
  DataflowTag: {
23
22
  CUSTOM_ENCODED_SQL_INJECTION,
24
23
  CUSTOM_ENCODED,
@@ -28,8 +27,10 @@ const {
28
27
  LIMITED_CHARS,
29
28
  UNTRUSTED
30
29
  },
31
- inspect
30
+ isString,
31
+ inspect,
32
32
  } = require('@contrast/common');
33
+ const { InstrumentationType: { RULE } } = require('../../../constants');
33
34
 
34
35
  const safeTags = [
35
36
  CUSTOM_ENCODED_SQL_INJECTION,
@@ -40,12 +41,19 @@ const safeTags = [
40
41
  LIMITED_CHARS,
41
42
  ];
42
43
 
44
+ /**
45
+ * @param {{
46
+ * assess: import('@contrast/assess').Assess,
47
+ * config: import('@contrast/config').Config,
48
+ * }} core
49
+ * @returns {import('@contrast/common').Installable}
50
+ */
43
51
  module.exports = function(core) {
44
52
  const {
45
53
  depHooks,
46
54
  patcher,
47
- scopes: { sources },
48
55
  assess: {
56
+ getSourceContext,
49
57
  eventFactory: { createSinkEvent },
50
58
  dataflow: {
51
59
  tracker,
@@ -65,11 +73,10 @@ module.exports = function(core) {
65
73
  }
66
74
 
67
75
  const pre = (module, file, obj, method) => (data) => {
68
- const store = sources.getStore()?.assess;
69
76
  if (
70
- !store ||
77
+ !getSourceContext(RULE, ruleId) ||
71
78
  !data.args[0] ||
72
- isLocked(SQL_INJECTION)
79
+ isLocked(ruleId)
73
80
  ) return;
74
81
 
75
82
  const val = getValueFromArgs(data.args);
@@ -106,7 +113,7 @@ module.exports = function(core) {
106
113
 
107
114
  if (event) {
108
115
  reportFindings({
109
- ruleId: SQL_INJECTION,
116
+ ruleId,
110
117
  sinkEvent: event,
111
118
  });
112
119
  }
@@ -0,0 +1,101 @@
1
+ /*
2
+ * Copyright: 2023 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
+
16
+ 'use strict';
17
+
18
+ const {
19
+ Rule: { UNTRUSTED_DESERIALIZATION: ruleId },
20
+ isString,
21
+ DataflowTag: {
22
+ UNTRUSTED
23
+ }
24
+ } = require('@contrast/common');
25
+ const { InstrumentationType: { RULE } } = require('../../../constants');
26
+ const { patchType } = require('../common');
27
+
28
+ /**
29
+ * @param {{
30
+ * assess: import('@contrast/assess').Assess,
31
+ * config: import('@contrast/config').Config,
32
+ * }} core
33
+ * @returns {import('@contrast/common').Installable}
34
+ */
35
+ module.exports = function(core) {
36
+ const {
37
+ depHooks,
38
+ patcher,
39
+ assess: {
40
+ getSourceContext,
41
+ eventFactory: { createSinkEvent },
42
+ dataflow: {
43
+ tracker,
44
+ sinks: { isVulnerable, reportFindings }
45
+ },
46
+ },
47
+ } = core;
48
+
49
+ core.assess.dataflow.sinks.nodeSerialize = {
50
+ install() {
51
+ depHooks.resolve({ name: 'node-serialize' }, (nodeSerialize) => {
52
+ patcher.patch(nodeSerialize, 'unserialize', {
53
+ name: 'node-serialize.unserialize',
54
+ patchType,
55
+ pre(data) {
56
+ if (!getSourceContext(RULE, ruleId) || !data.args[0]) return;
57
+
58
+ const [input] = data.args;
59
+ if (!isString(input)) return;
60
+
61
+ const strInfo = tracker.getData(input);
62
+ if (!strInfo || !isVulnerable(UNTRUSTED, [], strInfo.tags)) return;
63
+
64
+ const sinkEvent = createSinkEvent({
65
+ name: 'node-serialize.unserialize',
66
+ moduleName: 'node-serialize',
67
+ methodName: 'unserialize',
68
+ context: `node-serialize.unserialize(${strInfo.value})`,
69
+ history: [strInfo],
70
+ object: {
71
+ value: 'node-serialize',
72
+ tracked: false
73
+ },
74
+ args: [
75
+ {
76
+ value: strInfo.value,
77
+ tracked: true
78
+ },
79
+ ],
80
+ tags: strInfo.tags,
81
+ source: 'P0',
82
+ stacktraceOpts: {
83
+ contructorOpt: data.hooked,
84
+ prependFrames: [data.orig]
85
+ },
86
+ });
87
+
88
+ if (sinkEvent) {
89
+ reportFindings({
90
+ ruleId,
91
+ sinkEvent,
92
+ });
93
+ }
94
+ }
95
+ });
96
+ });
97
+ },
98
+ };
99
+
100
+ return core.assess.dataflow.sinks.nodeSerialize;
101
+ };
@@ -17,19 +17,33 @@
17
17
 
18
18
  const util = require('util');
19
19
  const {
20
- DataflowTag: { UNTRUSTED, SQL_ENCODED, LIMITED_CHARS, CUSTOM_VALIDATED, CUSTOM_ENCODED },
20
+ DataflowTag: {
21
+ CUSTOM_VALIDATED,
22
+ CUSTOM_ENCODED,
23
+ LIMITED_CHARS,
24
+ SQL_ENCODED,
25
+ UNTRUSTED,
26
+ },
21
27
  Rule: { SQL_INJECTION: ruleId },
22
28
  isString,
23
29
  } = require('@contrast/common');
30
+ const { InstrumentationType: { RULE } } = require('../../../constants');
24
31
  const { filterSafeTags, patchType } = require('../common');
25
32
 
33
+ /**
34
+ * @param {{
35
+ * assess: import('@contrast/assess').Assess,
36
+ * config: import('@contrast/config').Config,
37
+ * }} core
38
+ * @returns {import('@contrast/common').Installable}
39
+ */
26
40
  module.exports = function(core) {
27
41
  const {
28
42
  config,
29
43
  depHooks,
30
44
  patcher,
31
- scopes: { sources },
32
45
  assess: {
46
+ getSourceContext,
33
47
  eventFactory: { createSinkEvent },
34
48
  dataflow: {
35
49
  tracker,
@@ -50,8 +64,7 @@ module.exports = function(core) {
50
64
  const postgres = core.assess.dataflow.sinks.postgres = {};
51
65
 
52
66
  const preHook = (methodSignature) => (data) => {
53
- const assessStore = sources.getStore()?.assess;
54
- if (!assessStore || isLocked(ruleId)) return;
67
+ if (!getSourceContext(RULE, ruleId) || isLocked(ruleId)) return;
55
68
 
56
69
  const [arg0] = data.args;
57
70
  const query = arg0?.text || arg0;
@@ -17,7 +17,7 @@
17
17
 
18
18
  const util = require('util');
19
19
  const {
20
- Rule: { SQL_INJECTION },
20
+ Rule: { SQL_INJECTION: ruleId },
21
21
  DataflowTag: {
22
22
  UNTRUSTED,
23
23
  SQL_ENCODED,
@@ -26,15 +26,23 @@ const {
26
26
  CUSTOM_ENCODED,
27
27
  },
28
28
  } = require('@contrast/common');
29
+ const { InstrumentationType: { RULE } } = require('../../../constants');
29
30
  const { patchType, filterSafeTags } = require('../common');
30
31
 
32
+ /**
33
+ * @param {{
34
+ * assess: import('@contrast/assess').Assess,
35
+ * config: import('@contrast/config').Config,
36
+ * }} core
37
+ * @returns {import('@contrast/common').Installable}
38
+ */
31
39
  module.exports = function(core) {
32
40
  const {
33
41
  depHooks,
34
42
  patcher,
35
43
  config,
36
- scopes: { sources },
37
44
  assess: {
45
+ getSourceContext,
38
46
  eventFactory: { createSinkEvent },
39
47
  dataflow: {
40
48
  tracker,
@@ -61,10 +69,9 @@ module.exports = function(core) {
61
69
  name: sequelizeQueryPatchName,
62
70
  patchType,
63
71
  around(next, data) {
64
- const { args, hooked, orig } = data;
65
- const sourceContext = sources.getStore()?.assess;
66
- if (!sourceContext || !args[0]) return next();
72
+ if (!getSourceContext(RULE, ruleId) || !data.args[0]) return next();
67
73
 
74
+ const { args, hooked, orig } = data;
68
75
  const query = typeof args[0] === 'string' ? args[0] : args[0].query;
69
76
 
70
77
  try {
@@ -74,7 +81,7 @@ module.exports = function(core) {
74
81
  if (queryInfo && !isVulnerableQuery && config.assess.safe_positives.enable) {
75
82
  reportSafePositive({
76
83
  name: sequelizeQueryPatchName,
77
- ruleId: SQL_INJECTION,
84
+ ruleId,
78
85
  safeTags: filterSafeTags(safeTags, queryInfo),
79
86
  strInfo: {
80
87
  value: queryInfo?.value,
@@ -87,7 +94,7 @@ module.exports = function(core) {
87
94
  !queryInfo ||
88
95
  !isVulnerableQuery
89
96
  ) {
90
- return runInActiveSink(SQL_INJECTION, async () => await next());
97
+ return runInActiveSink(ruleId, async () => await next());
91
98
  }
92
99
 
93
100
  const sqlValue =
@@ -122,7 +129,7 @@ module.exports = function(core) {
122
129
 
123
130
  if (event) {
124
131
  reportFindings({
125
- ruleId: SQL_INJECTION,
132
+ ruleId,
126
133
  sinkEvent: event,
127
134
  });
128
135
  }
@@ -134,7 +141,7 @@ module.exports = function(core) {
134
141
  );
135
142
  }
136
143
 
137
- return runInActiveSink(SQL_INJECTION, async () => await next());
144
+ return runInActiveSink(ruleId, async () => await next());
138
145
  },
139
146
  });
140
147
  });
@@ -17,10 +17,17 @@
17
17
 
18
18
  const { patchType } = require('../common');
19
19
  const {
20
- DataflowTag: { UNTRUSTED, SQL_ENCODED, LIMITED_CHARS, CUSTOM_VALIDATED, CUSTOM_ENCODED },
21
- Rule: { SQL_INJECTION },
20
+ DataflowTag: {
21
+ CUSTOM_VALIDATED,
22
+ CUSTOM_ENCODED,
23
+ LIMITED_CHARS,
24
+ SQL_ENCODED,
25
+ UNTRUSTED,
26
+ },
27
+ Rule: { SQL_INJECTION: ruleId },
22
28
  isString
23
29
  } = require('@contrast/common');
30
+ const { InstrumentationType: { RULE } } = require('../../../constants');
24
31
 
25
32
  const safeTags = [
26
33
  SQL_ENCODED,
@@ -29,12 +36,19 @@ const safeTags = [
29
36
  CUSTOM_ENCODED,
30
37
  ];
31
38
 
39
+ /**
40
+ * @param {{
41
+ * assess: import('@contrast/assess').Assess,
42
+ * config: import('@contrast/config').Config,
43
+ * }} core
44
+ * @returns {import('@contrast/common').Installable}
45
+ */
32
46
  module.exports = function(core) {
33
47
  const {
34
48
  depHooks,
35
49
  patcher,
36
- scopes: { sources },
37
50
  assess: {
51
+ getSourceContext,
38
52
  eventFactory: { createSinkEvent },
39
53
  dataflow: {
40
54
  tracker,
@@ -44,12 +58,11 @@ module.exports = function(core) {
44
58
  } = core;
45
59
 
46
60
  const pre = (name, method) => (data) => {
47
- const store = sources.getStore()?.assess;
48
61
  if (
49
- !store ||
62
+ !getSourceContext(RULE, ruleId) ||
50
63
  !data.args[0] ||
51
64
  !isString(data.args[0]) ||
52
- isLocked(SQL_INJECTION)
65
+ isLocked(ruleId)
53
66
  ) return;
54
67
 
55
68
  const strInfo = tracker.getData(data.args[0]);
@@ -83,7 +96,7 @@ module.exports = function(core) {
83
96
 
84
97
  if (event) {
85
98
  reportFindings({
86
- ruleId: SQL_INJECTION,
99
+ ruleId,
87
100
  sinkEvent: event,
88
101
  });
89
102
  }