@contrast/assess 1.4.0 → 1.6.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 (59) hide show
  1. package/lib/dataflow/event-factory.js +41 -83
  2. package/lib/dataflow/index.js +0 -1
  3. package/lib/dataflow/propagation/install/array-prototype-join.js +3 -3
  4. package/lib/dataflow/propagation/install/contrast-methods/add.js +23 -16
  5. package/lib/dataflow/propagation/install/contrast-methods/tag.js +30 -22
  6. package/lib/dataflow/propagation/install/decode-uri-component.js +8 -5
  7. package/lib/dataflow/propagation/install/ejs/escape-xml.js +8 -5
  8. package/lib/dataflow/propagation/install/encode-uri-component.js +3 -3
  9. package/lib/dataflow/propagation/install/escape-html.js +10 -7
  10. package/lib/dataflow/propagation/install/escape.js +8 -5
  11. package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +8 -5
  12. package/lib/dataflow/propagation/install/mysql-connection-escape.js +8 -5
  13. package/lib/dataflow/propagation/install/pug-runtime-escape.js +3 -3
  14. package/lib/dataflow/propagation/install/querystring/parse.js +11 -6
  15. package/lib/dataflow/propagation/install/sql-template-strings.js +3 -3
  16. package/lib/dataflow/propagation/install/string/concat.js +4 -4
  17. package/lib/dataflow/propagation/install/string/format-methods.js +2 -2
  18. package/lib/dataflow/propagation/install/string/html-methods.js +5 -5
  19. package/lib/dataflow/propagation/install/string/index.js +1 -0
  20. package/lib/dataflow/propagation/install/string/match.js +3 -3
  21. package/lib/dataflow/propagation/install/string/replace.js +9 -5
  22. package/lib/dataflow/propagation/install/string/slice.js +104 -0
  23. package/lib/dataflow/propagation/install/string/split.js +4 -4
  24. package/lib/dataflow/propagation/install/string/substring.js +6 -4
  25. package/lib/dataflow/propagation/install/string/trim.js +2 -2
  26. package/lib/dataflow/propagation/install/unescape.js +8 -5
  27. package/lib/dataflow/propagation/install/url/domain-parsers.js +3 -3
  28. package/lib/dataflow/propagation/install/validator/hooks.js +2 -2
  29. package/lib/dataflow/propagation/install/validator/methods.js +60 -51
  30. package/lib/dataflow/sinks/index.js +15 -2
  31. package/lib/dataflow/sinks/install/child-process.js +224 -0
  32. package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +47 -23
  33. package/lib/dataflow/sinks/install/fs.js +136 -0
  34. package/lib/dataflow/sinks/install/http.js +48 -32
  35. package/lib/dataflow/sinks/install/koa/index.js +30 -0
  36. package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +122 -0
  37. package/lib/dataflow/sinks/install/marsdb.js +135 -0
  38. package/lib/dataflow/sinks/install/mongodb.js +205 -0
  39. package/lib/dataflow/sinks/install/mssql.js +19 -13
  40. package/lib/dataflow/sinks/install/mysql.js +122 -0
  41. package/lib/dataflow/sinks/install/postgres.js +40 -29
  42. package/lib/dataflow/sinks/install/sqlite3.js +99 -0
  43. package/lib/dataflow/sources/handler.js +19 -15
  44. package/lib/dataflow/sources/index.js +9 -0
  45. package/lib/dataflow/sources/install/busboy1.js +112 -0
  46. package/lib/dataflow/sources/install/fastify/fastify.js +23 -29
  47. package/lib/dataflow/sources/install/fastify/index.js +4 -5
  48. package/lib/dataflow/sources/install/formidable1.js +91 -0
  49. package/lib/dataflow/sources/install/http.js +35 -14
  50. package/lib/dataflow/sources/install/koa/index.js +32 -0
  51. package/lib/dataflow/sources/install/koa/koa-bodyparsers.js +92 -0
  52. package/lib/dataflow/sources/install/koa/koa-routers.js +84 -0
  53. package/lib/dataflow/sources/install/koa/koa2.js +103 -0
  54. package/lib/dataflow/sources/install/qs6.js +84 -0
  55. package/lib/dataflow/utils/is-vulnerable.js +1 -1
  56. package/package.json +2 -2
  57. package/lib/dataflow/signatures/index.js +0 -2006
  58. package/lib/dataflow/signatures/mssql.js +0 -49
  59. package/lib/dataflow/sources/install/fastify/cookie.js +0 -61
@@ -14,8 +14,13 @@
14
14
  */
15
15
 
16
16
  'use strict';
17
+
17
18
  const util = require('util');
18
19
  const querystring = require('querystring');
20
+ const {
21
+ DataflowTag: { URL_ENCODED }
22
+ } = require('@contrast/common');
23
+
19
24
  const { patchType } = require('../../common');
20
25
  const { createSubsetTags, createAppendTags } = require('../../../tag-utils');
21
26
 
@@ -46,18 +51,18 @@ module.exports = function(core) {
46
51
  history: [trackingData],
47
52
  object: {
48
53
  value: part,
49
- isTracked: true,
54
+ tracked: true,
50
55
  },
51
56
  args: data.origArgs.map((arg) => {
52
57
  const argInfo = tracker.getData(arg);
53
58
  return {
54
59
  value: argInfo ? argInfo.value : util.inspect(arg),
55
- isTracked: !!argInfo
60
+ tracked: !!argInfo
56
61
  };
57
62
  }),
58
63
  result: {
59
64
  value: result,
60
- isTracked: !!resultInfo
65
+ tracked: !!resultInfo
61
66
  },
62
67
  tags: tagRanges,
63
68
  stacktraceOpts: {
@@ -73,9 +78,9 @@ module.exports = function(core) {
73
78
  event.tags = createAppendTags(event.tags, resultInfo.tags, 0);
74
79
  Object.assign(resultInfo, event);
75
80
  }
76
- if (event.tags['url-encoded']) {
77
- delete event.tags['url-encoded'];
78
- event.removedTags = ['url-encoded'];
81
+ if (event.tags[URL_ENCODED]) {
82
+ delete event.tags[URL_ENCODED];
83
+ event.removedTags = [URL_ENCODED];
79
84
  }
80
85
  const { extern } = resultInfo || tracker.track(result, event);
81
86
  if (extern) {
@@ -57,13 +57,13 @@ module.exports = function(core) {
57
57
  name: 'sql-template-strings.SQL',
58
58
  object: {
59
59
  value: createModuleLabel('sql-template-strings', version),
60
- isTracked: false
60
+ tracked: false
61
61
  },
62
62
  result: {
63
63
  value: resultInfo ? resultInfo.value : resultValue,
64
- isTracked: true
64
+ tracked: true
65
65
  },
66
- args: [{ value: argInfo.value, isTracked: true }],
66
+ args: [{ value: argInfo.value, tracked: true }],
67
67
  tags: newTags,
68
68
  addedTags: ['sql-encoded'],
69
69
  history,
@@ -62,10 +62,10 @@ module.exports = function(core) {
62
62
 
63
63
  argsData.push({
64
64
  value: strInfo?.value ?? str,
65
- isTracked: !!strInfo
65
+ tracked: !!strInfo
66
66
  });
67
67
 
68
- globalOffset += str.length;
68
+ globalOffset += `${str}`.length;
69
69
  }
70
70
 
71
71
  if (history.size) {
@@ -73,11 +73,11 @@ module.exports = function(core) {
73
73
  name: 'String.prototype.concat',
74
74
  object: {
75
75
  value: objInfo?.value || String(obj),
76
- isTracked: !!objInfo
76
+ tracked: !!objInfo
77
77
  },
78
78
  result: {
79
79
  value: result,
80
- isTracked: true
80
+ tracked: true
81
81
  },
82
82
  args: argsData,
83
83
  tags: newTags,
@@ -46,11 +46,11 @@ module.exports = function(core) {
46
46
  name: `String.prototype.${method}`,
47
47
  object: {
48
48
  value: objInfo.value,
49
- isTracked: true
49
+ tracked: true
50
50
  },
51
51
  result: {
52
52
  value: result,
53
- isTracked: true
53
+ tracked: true
54
54
  },
55
55
  args: [],
56
56
  tags: objInfo.tags,
@@ -78,14 +78,14 @@ module.exports = function(core) {
78
78
  name: 'String.prototype.anchor',
79
79
  object: {
80
80
  value: objInfo?.value || String(obj),
81
- isTracked: !!objInfo
81
+ tracked: !!objInfo
82
82
  },
83
83
  result: {
84
84
  value: result,
85
- isTracked: true
85
+ tracked: true
86
86
  },
87
87
  args: [
88
- { value: arg, isTracked: !!argInfo }
88
+ { value: arg, tracked: !!argInfo }
89
89
  ],
90
90
  tags: adjustTags('anchor', objInfo?.tags, `${arg}`.length, argInfo?.tags),
91
91
  history: Array.from(history),
@@ -126,11 +126,11 @@ module.exports = function(core) {
126
126
  name: `String.prototype.${method}`,
127
127
  object: {
128
128
  value: objInfo.value,
129
- isTracked: true
129
+ tracked: true
130
130
  },
131
131
  result: {
132
132
  value: result,
133
- isTracked: true
133
+ tracked: true
134
134
  },
135
135
  args: [],
136
136
  tags: adjustTags(method, objInfo.tags),
@@ -33,6 +33,7 @@ module.exports = function(core) {
33
33
  require('./match')(core);
34
34
  require('./replace')(core);
35
35
  require('./split')(core);
36
+ require('./slice')(core);
36
37
  require('./substring')(core);
37
38
  require('./trim')(core);
38
39
 
@@ -37,19 +37,19 @@ module.exports = function(core) {
37
37
  history: [objInfo],
38
38
  object: {
39
39
  value: objInfo.value,
40
- isTracked: true,
40
+ tracked: true,
41
41
  },
42
42
  args: args.map((arg) => {
43
43
  const argInfo = tracker.getData(arg);
44
44
  return {
45
45
  value: argInfo ? argInfo.value : arg.toString(),
46
- isTracked: !!argInfo
46
+ tracked: !!argInfo
47
47
  };
48
48
  }),
49
49
  tags,
50
50
  result: {
51
51
  value: join(result),
52
- isTracked: false
52
+ tracked: false
53
53
  },
54
54
  stacktraceOpts: {
55
55
  constructorOpt: hooked,
@@ -15,6 +15,9 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const {
19
+ DataflowTag: { UNTRUSTED }
20
+ } = require('@contrast/common');
18
21
  const { patchType } = require('../../common');
19
22
  const { createSubsetTags, createAppendTags } = require('../../../tag-utils');
20
23
 
@@ -148,7 +151,8 @@ module.exports = function(core) {
148
151
  !sources.getStore()?.assess ||
149
152
  instrumentation.isLocked() ||
150
153
  !data.result ||
151
- !data._accumTags?.untrusted
154
+ // todo: can we reuse this optimization in other propagators? e.g those performing substring-like operations
155
+ !data._accumTags?.[UNTRUSTED]
152
156
  ) return;
153
157
 
154
158
  const { _replacementInfo, obj, args, result, hooked, orig } = data;
@@ -158,19 +162,19 @@ module.exports = function(core) {
158
162
  history: Array.from(data._history),
159
163
  object: {
160
164
  value: obj,
161
- isTracked: !!data._objInfo
165
+ tracked: !!data._objInfo
162
166
  },
163
167
  args: [{
164
168
  value: args[0].toString(),
165
- isTracked: !!tracker.getData(args[0])
169
+ tracked: !!tracker.getData(args[0])
166
170
  },
167
171
  {
168
172
  value: data._replacement,
169
- isTracked: !!_replacementInfo
173
+ tracked: !!_replacementInfo
170
174
  }],
171
175
  result: {
172
176
  value: result,
173
- isTracked: true
177
+ tracked: true
174
178
  },
175
179
  tags: data._accumTags,
176
180
  stacktraceOpts: {
@@ -0,0 +1,104 @@
1
+ /*
2
+ * Copyright: 2022 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
+ const { patchType } = require('../../common');
17
+ const { createSubsetTags } = require('../../../tag-utils');
18
+
19
+ module.exports = function(core) {
20
+ const {
21
+ scopes: { sources, instrumentation },
22
+ patcher,
23
+ assess: {
24
+ dataflow: { tracker, eventFactory: { createPropagationEvent } }
25
+ }
26
+ } = core;
27
+
28
+ function calculateSubsetRangeForSlice({ obj, args }) {
29
+ let [start, end] = args;
30
+ const hasSingleArg = end === undefined;
31
+
32
+ if (start < 0 && hasSingleArg || start < 0 && end < 0) {
33
+ start = obj.length - Math.abs(start);
34
+ end = obj.length - (Math.abs(end) || 0);
35
+ } else if (start > 0 && end < 0) {
36
+ end = obj.length - (Math.abs(end) || 0);
37
+ }
38
+
39
+ const subsetLen = (hasSingleArg ? obj.length - start : Math.abs(end - start)) - 1;
40
+
41
+ return {
42
+ startIdx: start,
43
+ subsetLen
44
+ };
45
+ }
46
+
47
+ return core.assess.dataflow.propagation.stringInstrumentation.slice = {
48
+ install() {
49
+ const name = 'String.prototype.slice';
50
+
51
+ patcher.patch(String.prototype, 'slice', {
52
+ name,
53
+ patchType,
54
+ post(data) {
55
+ const { name, args, obj, result, hooked, orig } = data;
56
+ if (!result || !sources.getStore() || instrumentation.isLocked()) return;
57
+
58
+ const objInfo = tracker.getData(obj);
59
+ if (!objInfo) return;
60
+
61
+ const rInfo = tracker.getData(result);
62
+ if (rInfo) {
63
+ // this may happen w/ trackedStr.slice(0) => trackedStr
64
+ return;
65
+ }
66
+
67
+ const { startIdx, subsetLen } = calculateSubsetRangeForSlice(data);
68
+ const tags = createSubsetTags(objInfo.tags, startIdx, subsetLen);
69
+ if (!tags) return;
70
+
71
+ const event = createPropagationEvent({
72
+ name,
73
+ history: [objInfo],
74
+ object: {
75
+ value: obj,
76
+ tracked: true,
77
+ },
78
+ args: args.map((arg) => ({
79
+ value: arg.toString(),
80
+ tracked: false
81
+ })),
82
+ result: {
83
+ value: result,
84
+ tracked: true
85
+ },
86
+ tags,
87
+ stacktraceOpts: {
88
+ constructorOpt: hooked,
89
+ prependFrames: [orig]
90
+ }
91
+ });
92
+ const { extern } = tracker.track(result, event);
93
+
94
+ if (extern) {
95
+ data.result = extern;
96
+ }
97
+ },
98
+ });
99
+ },
100
+ uninstall() {
101
+ String.prototype.slice = patcher.unwrap(String.prototype.slice);
102
+ },
103
+ };
104
+ };
@@ -50,7 +50,7 @@ module.exports = function(core) {
50
50
  ) return;
51
51
 
52
52
  const objInfo = tracker.getData(obj);
53
- if (!objInfo) return;
53
+ if (!objInfo || obj === result[0]) return;
54
54
 
55
55
  let idx = 0;
56
56
  for (let i = 0; i < result.length; i++) {
@@ -68,19 +68,19 @@ module.exports = function(core) {
68
68
  history: [objInfo],
69
69
  object: {
70
70
  value: obj,
71
- isTracked: true,
71
+ tracked: true,
72
72
  },
73
73
  args: args.map((arg) => {
74
74
  const argInfo = tracker.getData(arg);
75
75
  return {
76
76
  value: argInfo ? argInfo.value : arg.toString(),
77
- isTracked: !!argInfo
77
+ tracked: !!argInfo
78
78
  };
79
79
  }),
80
80
  tags,
81
81
  result: {
82
82
  value: join(result),
83
- isTracked: false
83
+ tracked: false
84
84
  },
85
85
  stacktraceOpts: {
86
86
  constructorOpt: hooked,
@@ -83,21 +83,23 @@ module.exports = function(core) {
83
83
  history: [objInfo],
84
84
  object: {
85
85
  value: obj,
86
- isTracked: true,
86
+ tracked: true,
87
87
  },
88
88
  args: args.map((arg) => ({
89
89
  value: arg.toString(),
90
- isTracked: false
90
+ tracked: false
91
91
  })),
92
92
  result: {
93
93
  value: result,
94
- isTracked: true
94
+ tracked: true
95
95
  },
96
96
  tags,
97
+ source: 'O',
97
98
  stacktraceOpts: {
98
99
  constructorOpt: hooked,
99
100
  prependFrames: [orig]
100
- }
101
+ },
102
+ target: 'R',
101
103
  });
102
104
  const { extern } = tracker.track(result, event);
103
105
 
@@ -63,11 +63,11 @@ module.exports = function(core) {
63
63
  history,
64
64
  object: {
65
65
  value: obj,
66
- isTracked: true
66
+ tracked: true
67
67
  },
68
68
  result: {
69
69
  value: result,
70
- isTracked: true
70
+ tracked: true
71
71
  },
72
72
  tags: newTags,
73
73
  stacktraceOpts: {
@@ -15,6 +15,9 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const {
19
+ DataflowTag: { WEAK_URL_ENCODED }
20
+ } = require('@contrast/common');
18
21
  const {
19
22
  createFullLengthCopyTags
20
23
  } = require('../../tag-utils');
@@ -45,7 +48,7 @@ module.exports = function(core) {
45
48
  const resultInfo = tracker.getData(result);
46
49
  const history = [argInfo];
47
50
  const newTags = createFullLengthCopyTags(argInfo.tags, result.length);
48
- delete newTags['weak-url-encoded'];
51
+ delete newTags[WEAK_URL_ENCODED];
49
52
 
50
53
  if (!Object.keys(newTags).length) return;
51
54
 
@@ -53,16 +56,16 @@ module.exports = function(core) {
53
56
  name: 'global.unescape',
54
57
  object: {
55
58
  value: createObjectLabel('global'),
56
- isTracked: false
59
+ tracked: false
57
60
  },
58
61
  result: {
59
62
  value: resultInfo ? resultInfo.value : result,
60
- isTracked: true
63
+ tracked: true
61
64
  },
62
- args: [{ value: argInfo.value, isTracked: true }],
65
+ args: [{ value: argInfo.value, tracked: true }],
63
66
  tags: newTags,
64
67
  history,
65
- removedTags: ['weak-url-encoded'],
68
+ removedTags: [WEAK_URL_ENCODED],
66
69
  stacktraceOpts: {
67
70
  constructorOpt: hooked,
68
71
  prependFrames: [orig]
@@ -52,13 +52,13 @@ module.exports = function(core) {
52
52
  name: `url.${method}`,
53
53
  object: {
54
54
  value: createModuleLabel('url', version),
55
- isTracked: false
55
+ tracked: false
56
56
  },
57
57
  result: {
58
58
  value: resultInfo ? resultInfo.value : result,
59
- isTracked: true
59
+ tracked: true
60
60
  },
61
- args: [{ value: argInfo.value, isTracked: true }],
61
+ args: [{ value: argInfo.value, tracked: true }],
62
62
  tags: createFullLengthCopyTags(argInfo.tags, result.length) || [],
63
63
  history,
64
64
  source: 'P',
@@ -33,11 +33,11 @@ module.exports = function(core) {
33
33
  history: [{ ...trackingData }],
34
34
  args: [{
35
35
  value: data.args[0],
36
- isTracked: true
36
+ tracked: true
37
37
  }],
38
38
  result: {
39
39
  value: data.result,
40
- isTracked: !!tracker.getData(data.result)
40
+ tracked: !!tracker.getData(data.result)
41
41
  },
42
42
  tags: {
43
43
  ...trackingData.tags,
@@ -15,57 +15,66 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const {
19
+ DataflowTag: {
20
+ ALPHANUM_SPACE_HYPHEN,
21
+ CUSTOM_VALIDATED,
22
+ HTML_ENCODED,
23
+ LIMITED_CHARS,
24
+ }
25
+ } = require('@contrast/common');
26
+
18
27
  module.exports = {
19
28
  validators: {
20
- isAfter: 'alphanum-space-hyphen',
21
- isAlpha: 'alphanum-space-hyphen',
22
- isAlphanumeric: 'alphanum-space-hyphen',
23
- isBase32: 'alphanum-space-hyphen',
24
- isBase58: 'alphanum-space-hyphen',
25
- isBase64: 'alphanum-space-hyphen',
26
- isBefore: 'alphanum-space-hyphen',
27
- isBIC: 'alphanum-space-hyphen',
28
- isBoolean: 'limited-chars',
29
- isBtcAddress: 'alphanum-space-hyphen',
30
- isCreditCard: 'limited-chars',
31
- isDate: 'limited-chars',
32
- isDecimal: 'limited-chars',
33
- isEAN: 'limited-chars',
34
- isEthereumAddress: 'alphanum-space-hyphen',
35
- isFloat: 'limited-chars',
36
- isHash: 'alphanum-space-hyphen',
37
- isHexadecimal: 'alphanum-space-hyphen',
38
- isHexColor: 'alphanum-space-hyphen',
39
- isHSL: 'alphanum-space-hyphen',
40
- isIBAN: 'limited-chars',
41
- isIdentityCard: 'alphanum-space-hyphen',
42
- isIMEI: 'limited-chars',
43
- isInt: 'limited-chars',
44
- isIP: 'limited-chars',
45
- isIPRange: 'limited-chars',
46
- isISBN: 'limited-chars',
47
- isISIN: 'limited-chars',
48
- isISO8601: 'alphanum-space-hyphen',
49
- isISO31661Alpha2: 'alphanum-space-hyphen',
50
- isISO31661Alpha3: 'alphanum-space-hyphen',
51
- isISRC: 'alphanum-space-hyphen',
52
- isISSN: 'limited-chars',
53
- isJWT: 'alphanum-space-hyphen',
54
- isLatLong: 'limited-chars',
55
- isLicensePlate: 'alphanum-space-hyphen',
56
- isMACAddress: 'alphanum-space-hyphen',
57
- isMagnetURI: 'alphanum-space-hyphen',
58
- isMD5: 'alphanum-space-hyphen',
59
- isMobilePhone: 'limited-chars',
60
- isNumeric: 'limited-chars',
61
- isOctal: 'alphanum-space-hyphen',
62
- isPassportNumber: 'limited-chars',
63
- isPostalCode: 'limited-chars',
64
- isSemVer: 'limited-chars',
65
- isTaxID: 'limited-chars',
66
- isUUID: 'alphanum-space-hyphen',
67
- isVAT: 'alphanum-space-hyphen',
68
- matches: 'custom-validated'
29
+ isAfter: ALPHANUM_SPACE_HYPHEN,
30
+ isAlpha: ALPHANUM_SPACE_HYPHEN,
31
+ isAlphanumeric: ALPHANUM_SPACE_HYPHEN,
32
+ isBase32: ALPHANUM_SPACE_HYPHEN,
33
+ isBase58: ALPHANUM_SPACE_HYPHEN,
34
+ isBase64: ALPHANUM_SPACE_HYPHEN,
35
+ isBefore: ALPHANUM_SPACE_HYPHEN,
36
+ isBIC: ALPHANUM_SPACE_HYPHEN,
37
+ isBoolean: LIMITED_CHARS,
38
+ isBtcAddress: ALPHANUM_SPACE_HYPHEN,
39
+ isCreditCard: LIMITED_CHARS,
40
+ isDate: LIMITED_CHARS,
41
+ isDecimal: LIMITED_CHARS,
42
+ isEAN: LIMITED_CHARS,
43
+ isEthereumAddress: ALPHANUM_SPACE_HYPHEN,
44
+ isFloat: LIMITED_CHARS,
45
+ isHash: ALPHANUM_SPACE_HYPHEN,
46
+ isHexadecimal: ALPHANUM_SPACE_HYPHEN,
47
+ isHexColor: ALPHANUM_SPACE_HYPHEN,
48
+ isHSL: ALPHANUM_SPACE_HYPHEN,
49
+ isIBAN: LIMITED_CHARS,
50
+ isIdentityCard: ALPHANUM_SPACE_HYPHEN,
51
+ isIMEI: LIMITED_CHARS,
52
+ isInt: LIMITED_CHARS,
53
+ isIP: LIMITED_CHARS,
54
+ isIPRange: LIMITED_CHARS,
55
+ isISBN: LIMITED_CHARS,
56
+ isISIN: LIMITED_CHARS,
57
+ isISO8601: ALPHANUM_SPACE_HYPHEN,
58
+ isISO31661Alpha2: ALPHANUM_SPACE_HYPHEN,
59
+ isISO31661Alpha3: ALPHANUM_SPACE_HYPHEN,
60
+ isISRC: ALPHANUM_SPACE_HYPHEN,
61
+ isISSN: LIMITED_CHARS,
62
+ isJWT: ALPHANUM_SPACE_HYPHEN,
63
+ isLatLong: LIMITED_CHARS,
64
+ isLicensePlate: ALPHANUM_SPACE_HYPHEN,
65
+ isMACAddress: ALPHANUM_SPACE_HYPHEN,
66
+ isMagnetURI: ALPHANUM_SPACE_HYPHEN,
67
+ isMD5: ALPHANUM_SPACE_HYPHEN,
68
+ isMobilePhone: LIMITED_CHARS,
69
+ isNumeric: LIMITED_CHARS,
70
+ isOctal: ALPHANUM_SPACE_HYPHEN,
71
+ isPassportNumber: LIMITED_CHARS,
72
+ isPostalCode: LIMITED_CHARS,
73
+ isSemVer: LIMITED_CHARS,
74
+ isTaxID: LIMITED_CHARS,
75
+ isUUID: ALPHANUM_SPACE_HYPHEN,
76
+ isVAT: ALPHANUM_SPACE_HYPHEN,
77
+ matches: CUSTOM_VALIDATED,
69
78
  },
70
79
  untrackers: [
71
80
  'equals',
@@ -74,9 +83,9 @@ module.exports = {
74
83
  'isRFC3339'
75
84
  ],
76
85
  sanitizers: {
77
- escape: 'html-encoded'
86
+ escape: HTML_ENCODED
78
87
  },
79
88
  custom: {
80
- isEmail: 'limited-chars'
89
+ isEmail: LIMITED_CHARS
81
90
  }
82
91
  };
@@ -21,21 +21,34 @@ const { isSafeContentType } = require('../utils/is-safe-content-type');
21
21
 
22
22
  module.exports = function (core) {
23
23
  const {
24
- messages
24
+ messages,
25
+ scopes: { sources }
25
26
  } = core;
26
27
 
27
28
  const sinks = core.assess.dataflow.sinks = {
28
29
  isVulnerable,
29
30
  isSafeContentType,
30
31
  reportFindings(data) {
31
- messages.emit(Event.ASSESS_DATAFLOW_FINDING, data);
32
+ const store = sources.getStore();
33
+ // these events need source correlation
34
+ messages.emit(Event.ASSESS_DATAFLOW_FINDING, {
35
+ sourceInfo: store?.sourceInfo,
36
+ ...data
37
+ });
32
38
  },
33
39
  };
34
40
 
35
41
  require('./install/fastify')(core);
42
+ require('./install/koa')(core);
43
+ require('./install/child-process')(core);
44
+ require('./install/fs')(core);
36
45
  require('./install/http')(core);
46
+ require('./install/mongodb')(core);
37
47
  require('./install/mssql')(core);
48
+ require('./install/mysql')(core);
38
49
  require('./install/postgres')(core);
50
+ require('./install/sqlite3')(core);
51
+ require('./install/marsdb')(core);
39
52
 
40
53
  sinks.install = function() {
41
54
  callChildComponentMethodsSync(core.assess.dataflow.sinks, 'install');