@contrast/assess 1.53.0 → 1.54.1

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 (83) hide show
  1. package/lib/crypto-analysis/install/math.js +0 -1
  2. package/lib/dataflow/propagation/common.js +6 -6
  3. package/lib/dataflow/propagation/install/JSON/parse.js +7 -3
  4. package/lib/dataflow/propagation/install/JSON/stringify.js +7 -6
  5. package/lib/dataflow/propagation/install/array-prototype-join.js +5 -8
  6. package/lib/dataflow/propagation/install/buffer.js +4 -4
  7. package/lib/dataflow/propagation/install/contrast-methods/add.js +42 -38
  8. package/lib/dataflow/propagation/install/contrast-methods/string.js +4 -2
  9. package/lib/dataflow/propagation/install/contrast-methods/tag.js +3 -1
  10. package/lib/dataflow/propagation/install/decode-uri-component.js +5 -7
  11. package/lib/dataflow/propagation/install/ejs/escape-xml.js +4 -3
  12. package/lib/dataflow/propagation/install/ejs/template.js +1 -1
  13. package/lib/dataflow/propagation/install/encode-uri.js +5 -7
  14. package/lib/dataflow/propagation/install/escape-html.js +4 -3
  15. package/lib/dataflow/propagation/install/escape.js +5 -7
  16. package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +4 -3
  17. package/lib/dataflow/propagation/install/joi/boolean.js +1 -3
  18. package/lib/dataflow/propagation/install/joi/expression.js +1 -3
  19. package/lib/dataflow/propagation/install/joi/number.js +1 -3
  20. package/lib/dataflow/propagation/install/joi/string-schema.js +2 -6
  21. package/lib/dataflow/propagation/install/joi/utils.js +2 -4
  22. package/lib/dataflow/propagation/install/joi/values.js +1 -3
  23. package/lib/dataflow/propagation/install/mongoose/schema-map.js +1 -3
  24. package/lib/dataflow/propagation/install/mongoose/schema-mixed.js +1 -3
  25. package/lib/dataflow/propagation/install/mongoose/schema-string.js +4 -5
  26. package/lib/dataflow/propagation/install/mustache-escape.js +4 -3
  27. package/lib/dataflow/propagation/install/mysql-connection-escape.js +9 -8
  28. package/lib/dataflow/propagation/install/path/basename.js +6 -7
  29. package/lib/dataflow/propagation/install/path/common.js +1 -0
  30. package/lib/dataflow/propagation/install/path/dirname.js +6 -8
  31. package/lib/dataflow/propagation/install/path/extname.js +8 -22
  32. package/lib/dataflow/propagation/install/path/format.js +6 -10
  33. package/lib/dataflow/propagation/install/path/join-and-resolve.js +7 -13
  34. package/lib/dataflow/propagation/install/path/normalize.js +8 -18
  35. package/lib/dataflow/propagation/install/path/parse.js +8 -18
  36. package/lib/dataflow/propagation/install/path/relative.js +8 -15
  37. package/lib/dataflow/propagation/install/path/toNamespacedPath.js +7 -18
  38. package/lib/dataflow/propagation/install/pug/index.js +1 -1
  39. package/lib/dataflow/propagation/install/pug-runtime-escape.js +6 -5
  40. package/lib/dataflow/propagation/install/querystring/escape.js +3 -1
  41. package/lib/dataflow/propagation/install/querystring/parse.js +3 -2
  42. package/lib/dataflow/propagation/install/querystring/stringify.js +4 -4
  43. package/lib/dataflow/propagation/install/reg-exp-prototype-exec.js +4 -3
  44. package/lib/dataflow/propagation/install/sequelize/query-generator.js +0 -1
  45. package/lib/dataflow/propagation/install/sequelize/sql-string.js +16 -17
  46. package/lib/dataflow/propagation/install/sql-template-strings.js +6 -10
  47. package/lib/dataflow/propagation/install/string/concat.js +4 -4
  48. package/lib/dataflow/propagation/install/string/format-methods.js +4 -4
  49. package/lib/dataflow/propagation/install/string/html-methods.js +5 -6
  50. package/lib/dataflow/propagation/install/string/index.js +4 -3
  51. package/lib/dataflow/propagation/install/string/match-all.js +7 -6
  52. package/lib/dataflow/propagation/install/string/match.js +10 -9
  53. package/lib/dataflow/propagation/install/string/replace.js +173 -158
  54. package/lib/dataflow/propagation/install/string/slice.js +4 -3
  55. package/lib/dataflow/propagation/install/string/split.js +11 -11
  56. package/lib/dataflow/propagation/install/string/substring.js +4 -3
  57. package/lib/dataflow/propagation/install/string/trim.js +4 -3
  58. package/lib/dataflow/propagation/install/unescape.js +6 -14
  59. package/lib/dataflow/propagation/install/url/domain-parsers.js +6 -5
  60. package/lib/dataflow/propagation/install/url/parse.js +17 -17
  61. package/lib/dataflow/propagation/install/url/searchParams.js +36 -25
  62. package/lib/dataflow/propagation/install/url/url.js +3 -2
  63. package/lib/dataflow/propagation/install/util-format.js +4 -3
  64. package/lib/dataflow/propagation/install/validator/hooks.js +0 -1
  65. package/lib/dataflow/sinks/install/eval.js +3 -1
  66. package/lib/dataflow/sinks/install/function.js +3 -4
  67. package/lib/dataflow/sinks/install/marsdb.js +3 -1
  68. package/lib/dataflow/sinks/install/mongodb.js +3 -1
  69. package/lib/dataflow/sinks/install/mssql.js +4 -3
  70. package/lib/dataflow/sinks/install/mysql.js +3 -1
  71. package/lib/dataflow/sinks/install/restify.js +3 -1
  72. package/lib/dataflow/sinks/install/sqlite3.js +4 -2
  73. package/lib/dataflow/sinks/install/vm.js +6 -4
  74. package/lib/dataflow/sources/handler.js +2 -3
  75. package/lib/dataflow/sources/install/fastify/fastify.js +4 -4
  76. package/lib/dataflow/tag-utils.js +15 -1
  77. package/lib/dataflow/tracker.js +0 -5
  78. package/lib/event-factory.js +1 -1
  79. package/lib/session-configuration/install/express-session.js +0 -1
  80. package/lib/session-configuration/install/fastify-cookie.js +0 -3
  81. package/lib/session-configuration/install/hapi.js +0 -1
  82. package/lib/session-configuration/install/koa.js +0 -3
  83. package/package.json +10 -10
@@ -16,7 +16,7 @@
16
16
  'use strict';
17
17
 
18
18
  const { createFullLengthCopyTags } = require('../../../tag-utils');
19
- const { patchType, createModuleLabel } = require('../../common');
19
+ const { patchType } = require('../../common');
20
20
 
21
21
  module.exports = function(core) {
22
22
  const {
@@ -40,7 +40,7 @@ module.exports = function(core) {
40
40
  patchType,
41
41
  usePerf: 'sync',
42
42
  post(data) {
43
- const { args, result, hooked, orig } = data;
43
+ const { args, result, hooked } = data;
44
44
  if (!result || !args[0] || !getPropagatorContext()) return;
45
45
 
46
46
  const argInfo = tracker.getData(args[0]);
@@ -54,9 +54,11 @@ module.exports = function(core) {
54
54
  name,
55
55
  moduleName: 'url',
56
56
  methodName: method,
57
- context: `url.${method}('${argInfo.value}')`,
57
+ get context() {
58
+ return `url.${method}('${argInfo.value}')`;
59
+ },
58
60
  object: {
59
- value: createModuleLabel('url', version),
61
+ value: 'url',
60
62
  tracked: false
61
63
  },
62
64
  result: {
@@ -70,7 +72,6 @@ module.exports = function(core) {
70
72
  target: 'R',
71
73
  stacktraceOpts: {
72
74
  constructorOpt: hooked,
73
- prependFrames: [orig]
74
75
  },
75
76
  });
76
77
 
@@ -16,6 +16,7 @@
16
16
  'use strict';
17
17
 
18
18
  const { patchType } = require('../../common');
19
+ const { createSubsetTags } = require('../../../tag-utils');
19
20
 
20
21
  module.exports = function(core) {
21
22
  const {
@@ -51,12 +52,14 @@ module.exports = function(core) {
51
52
  ]
52
53
  ];
53
54
 
54
- function getPropagationEvent(argInfo, partInfo, { name, result, hooked, orig }, parseQueryString = false) {
55
+ function getPropagationEvent(argInfo, { value, tags }, { name, result, hooked, orig }, parseQueryString = false) {
55
56
  return createPropagationEvent({
56
57
  name,
57
58
  moduleName: 'url',
58
59
  methodName: 'parse',
59
- context: `url.parse('${argInfo.value += parseQueryString ? "', true" : ''})`,
60
+ get context() {
61
+ return `url.parse('${argInfo.value += parseQueryString ? "', true" : ''})`;
62
+ },
60
63
  object: {
61
64
  value: 'url',
62
65
  tracked: false
@@ -65,14 +68,13 @@ module.exports = function(core) {
65
68
  value: inspect(result),
66
69
  tracked: true
67
70
  },
68
- args: [{ value: partInfo.value, tracked: true }],
69
- tags: partInfo.tags,
70
- history: [{ ...partInfo }],
71
+ args: [{ value, tracked: true }],
72
+ tags,
73
+ history: [{ ...argInfo }],
71
74
  source: 'P',
72
75
  target: 'R',
73
76
  stacktraceOpts: {
74
77
  constructorOpt: hooked,
75
- prependFrames: [orig]
76
78
  },
77
79
  });
78
80
  }
@@ -80,7 +82,6 @@ module.exports = function(core) {
80
82
  return core.assess.dataflow.propagation.urlInstrumentation.parse = {
81
83
  install() {
82
84
  depHooks.resolve({ name: 'url', version: '*' }, (url) => {
83
-
84
85
  const name = 'url.parse';
85
86
 
86
87
  patcher.patch(url, 'parse', {
@@ -98,7 +99,7 @@ module.exports = function(core) {
98
99
 
99
100
  const metadata = { name, result, hooked, orig };
100
101
  const traverse = function(href, url, keys, idx = 0) {
101
- let substr = href;
102
+ const substr = href;
102
103
  keys.forEach((key) => {
103
104
  if (typeof key === 'string') {
104
105
  const part = result[key];
@@ -117,20 +118,19 @@ module.exports = function(core) {
117
118
  });
118
119
  return;
119
120
  } else {
120
- const index = href.indexOf(part, idx - 1);
121
- substr = href.substring(index, index + part.length);
121
+ const index = url.href.indexOf(part, idx - 1);
122
+ const substrTags = createSubsetTags(argInfo.tags, index, part.length);
123
+ if (!substrTags) return;
122
124
  idx += part.length;
123
- }
124
125
 
125
- const partInfo = tracker.getData(substr);
126
- if (!partInfo) return;
126
+ const event = getPropagationEvent(argInfo, { value: part, tags: substrTags }, metadata);
127
127
 
128
- const event = getPropagationEvent(argInfo, partInfo, metadata);
128
+ if (!event) return;
129
129
 
130
- if (!event) return;
130
+ const { extern } = tracker.track(part, event);
131
131
 
132
- Object.assign(partInfo, event);
133
- result[key] = substr;
132
+ if (extern) result[key] = extern;
133
+ }
134
134
  }
135
135
  } else {
136
136
  traverse(substr, url, key, 0);
@@ -15,8 +15,8 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { isString, primordials: { StringPrototypeConcat, StringPrototypeReplaceAll } } = require('@contrast/common');
19
- const { createAppendTags } = require('../../../tag-utils');
18
+ const { isString, primordials: { StringPrototypeConcat, StringPrototypeReplaceAll, StringPrototypeSplit, StringPrototypeSubstring } } = require('@contrast/common');
19
+ const { createAppendTags, createSubsetTags } = require('../../../tag-utils');
20
20
  const { patchType } = require('../../common');
21
21
 
22
22
  module.exports = function(core) {
@@ -31,12 +31,14 @@ module.exports = function(core) {
31
31
  }
32
32
  } = core;
33
33
 
34
- function getPropagationEvent(params, paramInfo, data) {
34
+ function getPropagationEvent(params, tags, data, history) {
35
35
  return createPropagationEvent({
36
36
  name: 'url.URLSearchParams',
37
37
  moduleName: 'url',
38
38
  methodName: 'URLSearchParams',
39
- context: `url.URLSearchParams('${inspect(params)}')`,
39
+ get context() {
40
+ return `url.URLSearchParams('${inspect(params)}')`;
41
+ },
40
42
  object: {
41
43
  value: 'url',
42
44
  tracked: false
@@ -46,13 +48,12 @@ module.exports = function(core) {
46
48
  tracked: true
47
49
  },
48
50
  args: [{ value: inspect(params), tracked: false }],
49
- tags: paramInfo.tags,
50
- history: [paramInfo],
51
+ tags,
52
+ history,
51
53
  source: 'P',
52
54
  target: 'R',
53
55
  stacktraceOpts: {
54
56
  constructorOpt: data.hooked,
55
- prependFrames: [data.orig]
56
57
  },
57
58
  });
58
59
  }
@@ -73,28 +74,39 @@ module.exports = function(core) {
73
74
  const [params] = args;
74
75
 
75
76
  if (isString(params)) {
76
- params.split('&').forEach((query) => {
77
+ const paramsInfo = tracker.getData(params);
78
+ if (!paramsInfo) return;
79
+ let idx = 0;
80
+ StringPrototypeSplit.call(params, '&').forEach((query) => {
77
81
  const endIdx = query.indexOf('=');
78
82
  // we don't want to create a propagation event by splitting off
79
83
  // the '?'. so if there start at index 1 else 0.
80
- const key = query.substring(query[0] === '?' ? 1 : 0, endIdx);
81
- const param = query.substring(endIdx + 1, query.length);
82
-
83
- const keyInfo = tracker.getData(key);
84
- const paramInfo = tracker.getData(param);
85
-
86
- if (keyInfo) {
87
- const event = getPropagationEvent(params, keyInfo, data);
88
- if (event) Object.assign(keyInfo, event);
84
+ const keyIdx = query[0] === '?' ? 1 : 0;
85
+ const key = StringPrototypeSubstring.call(query, keyIdx, endIdx);
86
+ const param = StringPrototypeSubstring.call(query, endIdx + 1, query.length);
87
+
88
+ idx += params.indexOf(query, idx);
89
+ const keyTags = createSubsetTags(paramsInfo.tags, idx + keyIdx, key.length);
90
+ const paramTags = createSubsetTags(paramsInfo.tags, key.length + idx + keyIdx + 1, param.length);
91
+
92
+ if (keyTags) {
93
+ const event = getPropagationEvent(params, keyTags, data, [paramsInfo]);
94
+ if (event) {
95
+ const { extern } = tracker.track(key, event);
96
+ if (extern) {
97
+ result.delete(key);
98
+ result.set(extern, param);
99
+ }
100
+ }
89
101
  }
90
102
 
91
- if (paramInfo) {
92
- const event = getPropagationEvent(params, paramInfo, data);
93
- if (event) Object.assign(paramInfo, event);
103
+ if (paramTags) {
104
+ const event = getPropagationEvent(params, paramTags, data, [paramsInfo]);
105
+ if (event) {
106
+ const { extern } = tracker.track(param, event);
107
+ if (extern) result.set(key, extern);
108
+ }
94
109
  }
95
-
96
- if (keyInfo) result.delete(key);
97
- result.set(key, param);
98
110
  });
99
111
  }
100
112
 
@@ -103,7 +115,7 @@ module.exports = function(core) {
103
115
  const paramInfo = tracker.getData(params[key]);
104
116
  if (!paramInfo) return;
105
117
 
106
- const event = getPropagationEvent(params, paramInfo, data);
118
+ const event = getPropagationEvent(params, paramInfo.tags, data, [paramInfo]);
107
119
  if (!event) return;
108
120
 
109
121
  Object.assign(paramInfo, event);
@@ -167,7 +179,6 @@ module.exports = function(core) {
167
179
 
168
180
  if (Object.keys(finalTags).length) {
169
181
  const event = createPropagationEvent({
170
- args: [],
171
182
  context: `${inspect(params)}.toString()`,
172
183
  moduleName: 'url',
173
184
  methodName: 'URLSearchParams.toString',
@@ -62,7 +62,9 @@ module.exports = function(core) {
62
62
  name: 'url.URL',
63
63
  moduleName: 'url',
64
64
  methodName: 'URL',
65
- context: `url.URL('${strInfo.value}')`,
65
+ get context() {
66
+ return `url.URL('${strInfo.value}')`;
67
+ },
66
68
  object: {
67
69
  value: 'url',
68
70
  tracked: false
@@ -78,7 +80,6 @@ module.exports = function(core) {
78
80
  target: 'R',
79
81
  stacktraceOpts: {
80
82
  constructorOpt: data.hooked,
81
- prependFrames: [data.orig]
82
83
  },
83
84
  });
84
85
  }
@@ -40,7 +40,7 @@ module.exports = function(core) {
40
40
  patchType,
41
41
  usePerf: 'sync',
42
42
  post(data) {
43
- const { args, result, hooked, orig } = data;
43
+ const { args, result, hooked } = data;
44
44
  if (!result || !args[0] || !isString(args[0]) || !getPropagatorContext()) return;
45
45
 
46
46
  let idx = 0;
@@ -114,7 +114,9 @@ module.exports = function(core) {
114
114
  name,
115
115
  moduleName: 'util',
116
116
  methodName: 'format',
117
- context: `util.format(${eventArgs.map((arg) => `'${arg.value}'`)})`,
117
+ get context() {
118
+ return `util.format(${eventArgs.map((arg) => `'${arg.value}'`)})`;
119
+ },
118
120
  object: {
119
121
  value: 'util',
120
122
  tracked: false
@@ -130,7 +132,6 @@ module.exports = function(core) {
130
132
  target: 'R',
131
133
  stacktraceOpts: {
132
134
  constructorOpt: hooked,
133
- prependFrames: [orig]
134
135
  },
135
136
  });
136
137
 
@@ -53,7 +53,6 @@ module.exports = function (core) {
53
53
  },
54
54
  stacktraceData: {
55
55
  constructorOpt: data.hooked,
56
- prependFrames: [data.orig]
57
56
  },
58
57
  source: 'P1',
59
58
  target
@@ -104,7 +104,9 @@ module.exports = function (core) {
104
104
  if (isArgVulnerable) {
105
105
  const event = createSinkEvent({
106
106
  name: 'eval',
107
- context: `eval('${strInfo.value}')`,
107
+ get context() {
108
+ return `eval('${strInfo.value}')`;
109
+ },
108
110
  history: [strInfo],
109
111
  object: {
110
112
  value: 'global',
@@ -113,10 +113,9 @@ module.exports = function (core) {
113
113
  });
114
114
  const event = createSinkEvent({
115
115
  name,
116
- context: `${name}(${ArrayPrototypeJoin.call(
117
- args.map((a) => a.inspectedValue),
118
- ', '
119
- )})`,
116
+ get context() {
117
+ return `${name}(${ArrayPrototypeJoin.call(args.map((a) => a.inspectedValue), ', ')})`;
118
+ },
120
119
  history: [strInfo],
121
120
  object: {
122
121
  value: 'global.ContrastMethods',
@@ -105,7 +105,9 @@ module.exports = function (core) {
105
105
 
106
106
  const sinkEvent = createSinkEvent({
107
107
  args,
108
- context: `marsdb.Collection.${method}(${args.map((a) => a.value)})`,
108
+ get context() {
109
+ return `marsdb.Collection.${method}(${args.map((a) => a.value)})`;
110
+ },
109
111
  moduleName: 'marsdb',
110
112
  methodName: `Collection.prototype.${method}`,
111
113
  history: [strInfo],
@@ -337,7 +337,9 @@ module.exports = function (core) {
337
337
  const resultVal = args[args.length - 1].value.startsWith('[Function') ? '' : 'Promise';
338
338
  const sinkEvent = createSinkEvent({
339
339
  args,
340
- context: `${objName}.${method}(${args.map((a, idx) => isString(origArgs[idx]) ? `'${a.value}'` : a.value)})`,
340
+ get context() {
341
+ return `${objName}.${method}(${args.map((a, idx) => isString(origArgs[idx]) ? `'${a.value}'` : a.value)})`;
342
+ },
341
343
  history: [vulnInfo.strInfo],
342
344
  object: {
343
345
  tracked: false,
@@ -26,7 +26,6 @@ const {
26
26
  Rule: { SQL_INJECTION: ruleId },
27
27
  isString,
28
28
  } = require('@contrast/common');
29
- const { createModuleLabel } = require('../../propagation/common');
30
29
  const { patchType, filterSafeTags } = require('../common');
31
30
 
32
31
  const safeTags = [
@@ -75,10 +74,12 @@ module.exports = function (core) {
75
74
  name,
76
75
  moduleName: 'mssql',
77
76
  methodName: `${obj}.prototype.${method}`,
78
- context: `mssql.${obj}.${method}('${strInfo.value}')`,
77
+ get context() {
78
+ return `mssql.${obj}.${method}('${strInfo.value}')`;
79
+ },
79
80
  history: [strInfo],
80
81
  object: {
81
- value: `[${createModuleLabel('mssql', version)}].${obj}`,
82
+ value: `mssql.${obj}`,
82
83
  tracked: false,
83
84
  },
84
85
  args: [
@@ -91,7 +91,9 @@ module.exports = function(core) {
91
91
  name: `${module}/${file}`,
92
92
  moduleName: module,
93
93
  methodName: `prototype.${method}`,
94
- context: `${module}.${method}(${inspect(data.args[0])})`,
94
+ get context() {
95
+ return `${module}.${method}(${inspect(data.args[0])})`;
96
+ },
95
97
  history: [strInfo],
96
98
  object: {
97
99
  value: `${module}.${obj}`,
@@ -186,7 +186,9 @@ module.exports = function(core) {
186
186
  const { tags, args } = getAdjustedValues(data.args, vulns, vulnArgIdx);
187
187
  const sinkEvent = createSinkEvent({
188
188
  args,
189
- context: `res.redirect(${ArrayPrototypeJoin.call(args.map((a) => a.value))})`,
189
+ get context() {
190
+ return `res.redirect(${ArrayPrototypeJoin.call(args.map((a) => a.value))})`;
191
+ },
190
192
  history,
191
193
  tags,
192
194
  source: 'P0',
@@ -74,10 +74,12 @@ module.exports = function(core) {
74
74
  name,
75
75
  moduleName: 'sqlite3',
76
76
  methodName: `Database.prototype.${method}`,
77
- context: `db.${method}('${strInfo.value}')`,
77
+ get context() {
78
+ return `db.${method}('${strInfo.value}')`;
79
+ },
78
80
  history: [strInfo],
79
81
  object: {
80
- value: '[Module<sqlite3>].Database',
82
+ value: 'sqlite3.Database',
81
83
  tracked: false,
82
84
  },
83
85
  args: [
@@ -205,10 +205,12 @@ module.exports = function (core) {
205
205
  if (vulnerableArg) {
206
206
  const event = createSinkEvent({
207
207
  name,
208
- context: `${name}(${ArrayPrototypeJoin.call(
209
- argsInfo.map((a) => a.ctxValue),
210
- ', '
211
- )})`,
208
+ get context() {
209
+ return `${name}(${ArrayPrototypeJoin.call(
210
+ argsInfo.map((a) => a.ctxValue),
211
+ ', '
212
+ )})`;
213
+ },
212
214
  history: [vulnerableArg.strInfo],
213
215
  object: {
214
216
  value: methodPath.includes('prototype')
@@ -19,6 +19,7 @@ const {
19
19
  InputType,
20
20
  DataflowTag,
21
21
  isString,
22
+ empties,
22
23
  primordials: {
23
24
  ArrayPrototypeJoin,
24
25
  StringPrototypeToLowerCase
@@ -43,8 +44,6 @@ module.exports = Core.makeComponent({
43
44
 
44
45
  const logger = core.logger.child({ name: 'contrast:sources' });
45
46
 
46
- const emptyStack = Object.freeze([]);
47
-
48
47
  sources.createTags = function createTags({ inputType, fieldName = '', value, tagNames }) {
49
48
  if (!value?.length) {
50
49
  return null;
@@ -70,7 +69,7 @@ module.exports = Core.makeComponent({
70
69
 
71
70
  sources.createStacktrace = function(stacktraceOpts) {
72
71
  return config.assess.stacktraces === 'NONE' || config.assess.stacktraces === 'SINK'
73
- ? emptyStack
72
+ ? empties.ARRAY
74
73
  : createSnapshot(stacktraceOpts)();
75
74
  };
76
75
 
@@ -36,14 +36,14 @@ module.exports = function (core) {
36
36
  patchType,
37
37
  post({ result: server, funcKey }) {
38
38
  server.addHook('preValidation', function preValidationHandler(request, reply, done) {
39
+ const sourceContext = getSourceContext();
40
+ if (!sourceContext) return done();
41
+
39
42
  const bodyType = request?.headers?.['content-type']?.includes('/json')
40
43
  ? InputType.JSON_VALUE
41
44
  : typeof request.body == 'object'
42
45
  ? InputType.PARAMETER_VALUE
43
46
  : InputType.BODY;
44
- const sourceContext = getSourceContext();
45
-
46
- if (!sourceContext) return;
47
47
 
48
48
  [
49
49
  { key: 'query', inputType: InputType.QUERYSTRING, alreadyTrackedFlag: 'parsedQuery' },
@@ -71,7 +71,7 @@ module.exports = function (core) {
71
71
  }
72
72
  });
73
73
 
74
- done();
74
+ return done();
75
75
  });
76
76
  },
77
77
  }));
@@ -14,7 +14,7 @@
14
14
  */
15
15
  'use strict';
16
16
 
17
- const { empties, primordials: { StringPrototypeSplit } } = require('@contrast/common');
17
+ const { empties, primordials: { StringPrototypeSplit, StringPrototypeSubstr } } = require('@contrast/common');
18
18
 
19
19
  //
20
20
  // This module implements tag range manipulation functions. There are generally
@@ -536,6 +536,19 @@ function getAdjustedUntrackedValue(origValue) {
536
536
  return origValue?.constructor?.name ?? (origValue === null ? 'null' : typeof origValue);
537
537
  }
538
538
 
539
+ /**
540
+ * Truncation spec: https://github.com/Contrast-Security-Inc/assess-specifications/blob/master/vulnerability/truncate-event-snapshots.md
541
+ * While the spec calls to truncate the middle of strings, we're going to just chop off the end.
542
+ * This way we don't have to recalculate all of the tag ranges to adjust for truncating.
543
+ * @param {string} str input string to be truncated
544
+ * @param {number} len
545
+ * @returns {string}
546
+ */
547
+ function truncateStringValue(str, len = 103) {
548
+ if (str.length <= len) return str;
549
+ return `${StringPrototypeSubstr.call(str, 0, len)}...`;
550
+ }
551
+
539
552
  module.exports = {
540
553
  createSubsetTags,
541
554
  createAppendTags,
@@ -546,4 +559,5 @@ module.exports = {
546
559
  createOverlappingTags,
547
560
  createEscapeTagRanges,
548
561
  getAdjustedUntrackedValue,
562
+ truncateStringValue,
549
563
  };
@@ -37,10 +37,6 @@ module.exports = function tracker(core) {
37
37
  return objMap.get(value) || null;
38
38
  }
39
39
 
40
- function isTracked(value) {
41
- return distringuish.isExternal(value);
42
- }
43
-
44
40
  function track(value, metadata) {
45
41
  let ret = Object.create(null);
46
42
 
@@ -152,6 +148,5 @@ module.exports = function tracker(core) {
152
148
  untrack,
153
149
  getData,
154
150
  getInfo: getData,
155
- isTracked,
156
151
  };
157
152
  };
@@ -45,7 +45,7 @@ module.exports = Core.makeComponent({
45
45
 
46
46
  eventFactory.createdEvents = new WeakSet();
47
47
 
48
- eventFactory.createSourceEvent = function(data = {}) {
48
+ eventFactory.createSourceEvent = function(data) {
49
49
  if (!data.result?.value) {
50
50
  logger.debug(SOURCE_EVENT_MSG, `invalid result: ${data.name}`);
51
51
  return null;
@@ -69,7 +69,6 @@ module.exports = function (core) {
69
69
  value: optionsString,
70
70
  }],
71
71
  context: `expressSession(${optionsString})`,
72
- history: [],
73
72
  name: 'express.hookedSessionConstructor',
74
73
  moduleName: 'express-session',
75
74
  methodName: '',
@@ -59,7 +59,6 @@ module.exports = function (core) {
59
59
  value: displayArg
60
60
  }],
61
61
  context: `fastifyCookie(${displayArg})`,
62
- history: [],
63
62
  name: 'fastifyCookie',
64
63
  moduleName: '@fastify/cookie',
65
64
  methodName: '',
@@ -71,8 +70,6 @@ module.exports = function (core) {
71
70
  tracked: false,
72
71
  },
73
72
  source: 'P0',
74
- stack: [],
75
- tags: {},
76
73
  framework: '@fastify/cookie',
77
74
  });
78
75
 
@@ -56,7 +56,6 @@ module.exports = function (core) {
56
56
  value: inspect(options),
57
57
  }],
58
58
  context: `state(${inspect(data.args)})`,
59
- history: [],
60
59
  name: `hapi.${server}.state`,
61
60
  moduleName: 'hapi',
62
61
  methodName: '',
@@ -72,7 +72,6 @@ module.exports = function (core) {
72
72
  value: displayArg
73
73
  }],
74
74
  context: `ctx.cookies.set(${displayArg})`,
75
- history: [],
76
75
  name: 'koaCookie',
77
76
  moduleName: 'koa',
78
77
  methodName: '',
@@ -84,8 +83,6 @@ module.exports = function (core) {
84
83
  tracked: false,
85
84
  },
86
85
  source: 'P',
87
- stack: [],
88
- tags: {},
89
86
  framework: 'koa',
90
87
  });
91
88
  if (!httpOnly) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/assess",
3
- "version": "1.53.0",
3
+ "version": "1.54.1",
4
4
  "description": "Contrast service providing framework-agnostic Assess support",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -21,16 +21,16 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@contrast/common": "1.32.0",
24
- "@contrast/config": "1.45.0",
25
- "@contrast/core": "1.50.0",
26
- "@contrast/dep-hooks": "1.19.0",
24
+ "@contrast/config": "1.46.0",
25
+ "@contrast/core": "1.51.0",
26
+ "@contrast/dep-hooks": "1.20.0",
27
27
  "@contrast/distringuish": "^5.1.0",
28
- "@contrast/instrumentation": "1.29.0",
29
- "@contrast/logger": "1.23.0",
30
- "@contrast/patcher": "1.22.0",
31
- "@contrast/rewriter": "1.26.0",
32
- "@contrast/route-coverage": "1.41.0",
33
- "@contrast/scopes": "1.20.0",
28
+ "@contrast/instrumentation": "1.30.0",
29
+ "@contrast/logger": "1.24.0",
30
+ "@contrast/patcher": "1.23.0",
31
+ "@contrast/rewriter": "1.27.0",
32
+ "@contrast/route-coverage": "1.42.0",
33
+ "@contrast/scopes": "1.21.0",
34
34
  "semver": "^7.6.0"
35
35
  }
36
36
  }