@contrast/assess 1.8.0 → 1.9.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 (62) hide show
  1. package/lib/dataflow/event-factory.js +17 -13
  2. package/lib/dataflow/propagation/index.js +3 -0
  3. package/lib/dataflow/propagation/install/JSON/index.js +1 -0
  4. package/lib/dataflow/propagation/install/JSON/parse-fn.js +248 -0
  5. package/lib/dataflow/propagation/install/JSON/parse.js +196 -0
  6. package/lib/dataflow/propagation/install/JSON/stringify.js +5 -3
  7. package/lib/dataflow/propagation/install/array-prototype-join.js +21 -14
  8. package/lib/dataflow/propagation/install/buffer.js +2 -0
  9. package/lib/dataflow/propagation/install/contrast-methods/add.js +2 -0
  10. package/lib/dataflow/propagation/install/contrast-methods/index.js +1 -0
  11. package/lib/dataflow/propagation/install/contrast-methods/number.js +58 -0
  12. package/lib/dataflow/propagation/install/contrast-methods/string.js +53 -6
  13. package/lib/dataflow/propagation/install/contrast-methods/tag.js +3 -1
  14. package/lib/dataflow/propagation/install/decode-uri-component.js +9 -2
  15. package/lib/dataflow/propagation/install/ejs/escape-xml.js +8 -2
  16. package/lib/dataflow/propagation/install/encode-uri-component.js +9 -2
  17. package/lib/dataflow/propagation/install/escape-html.js +13 -5
  18. package/lib/dataflow/propagation/install/escape.js +9 -2
  19. package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +11 -4
  20. package/lib/dataflow/propagation/install/isnumeric-0.js +59 -0
  21. package/lib/dataflow/propagation/install/mongoose/index.js +36 -0
  22. package/lib/dataflow/propagation/install/mongoose/schema-string.js +156 -0
  23. package/lib/dataflow/propagation/install/mysql-connection-escape.js +5 -0
  24. package/lib/dataflow/propagation/install/parse-int.js +60 -0
  25. package/lib/dataflow/propagation/install/pug-runtime-escape.js +9 -2
  26. package/lib/dataflow/propagation/install/querystring/parse.js +11 -9
  27. package/lib/dataflow/propagation/install/sequelize.js +6 -3
  28. package/lib/dataflow/propagation/install/sql-template-strings.js +9 -2
  29. package/lib/dataflow/propagation/install/string/concat.js +8 -2
  30. package/lib/dataflow/propagation/install/string/format-methods.js +7 -2
  31. package/lib/dataflow/propagation/install/string/html-methods.js +15 -5
  32. package/lib/dataflow/propagation/install/string/match.js +14 -9
  33. package/lib/dataflow/propagation/install/string/replace.js +22 -14
  34. package/lib/dataflow/propagation/install/string/slice.js +13 -5
  35. package/lib/dataflow/propagation/install/string/split.js +15 -11
  36. package/lib/dataflow/propagation/install/string/substring.js +16 -6
  37. package/lib/dataflow/propagation/install/string/trim.js +3 -0
  38. package/lib/dataflow/propagation/install/unescape.js +9 -2
  39. package/lib/dataflow/propagation/install/url/domain-parsers.js +7 -2
  40. package/lib/dataflow/propagation/install/validator/hooks.js +6 -2
  41. package/lib/dataflow/sinks/install/child-process.js +116 -50
  42. package/lib/dataflow/sinks/install/express/unvalidated-redirect.js +6 -3
  43. package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +7 -4
  44. package/lib/dataflow/sinks/install/fs.js +44 -12
  45. package/lib/dataflow/sinks/install/http.js +5 -2
  46. package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +7 -4
  47. package/lib/dataflow/sinks/install/marsdb.js +3 -0
  48. package/lib/dataflow/sinks/install/mongodb.js +3 -1
  49. package/lib/dataflow/sinks/install/mssql.js +9 -2
  50. package/lib/dataflow/sinks/install/mysql.js +9 -4
  51. package/lib/dataflow/sinks/install/postgres.js +6 -3
  52. package/lib/dataflow/sinks/install/sequelize.js +7 -5
  53. package/lib/dataflow/sinks/install/sqlite3.js +7 -3
  54. package/lib/dataflow/sources/handler.js +2 -1
  55. package/lib/dataflow/sources/install/http.js +1 -1
  56. package/lib/dataflow/tag-utils.js +25 -1
  57. package/lib/dataflow/tracker.js +6 -6
  58. package/lib/index.js +2 -0
  59. package/lib/response-scanning/handlers/utils.js +2 -2
  60. package/lib/session-configuration/index.js +34 -0
  61. package/lib/session-configuration/install/http.js +79 -0
  62. package/package.json +2 -2
@@ -34,8 +34,10 @@ module.exports = function(core) {
34
34
  install() {
35
35
  depHooks.resolve({ name: 'url' }, (url, version) => {
36
36
  ['domainToASCII', 'domainToUnicode'].forEach((method) => {
37
+ const name = `url.${method}`;
38
+
37
39
  patcher.patch(url, method, {
38
- name: `url.${method}`,
40
+ name,
39
41
  patchType,
40
42
  post(data) {
41
43
  const { args, result, hooked, orig } = data;
@@ -49,7 +51,10 @@ module.exports = function(core) {
49
51
  const history = [argInfo];
50
52
 
51
53
  const event = createPropagationEvent({
52
- name: `url.${method}`,
54
+ name,
55
+ moduleName: 'url',
56
+ methodName: method,
57
+ context: `url.${method}('${argInfo.value}')`,
53
58
  object: {
54
59
  value: createModuleLabel('url', version),
55
60
  tracked: false
@@ -30,9 +30,12 @@ module.exports = function(core) {
30
30
  function createValidatorPropagationEvent(method, data, trackingData, newTags, target) {
31
31
  return createPropagationEvent({
32
32
  name: `validator.${method}`,
33
+ moduleName: 'validator',
34
+ methodName: method,
35
+ context: `validator.${method}('${trackingData.value}')`,
33
36
  history: [{ ...trackingData }],
34
37
  args: [{
35
- value: data.args[0],
38
+ value: trackingData.value,
36
39
  tracked: true
37
40
  }],
38
41
  result: {
@@ -59,8 +62,9 @@ module.exports = function(core) {
59
62
  { name: 'validator', file: `lib/${validator}` },
60
63
  (index) => {
61
64
  const patchFn = typeof index === 'object' ? index.default : index;
65
+ const name = `validator.${validator}`;
62
66
  return patcher.patch(patchFn, {
63
- name: `validator.${validator}`,
67
+ name,
64
68
  patchType,
65
69
  post(data) {
66
70
  const matches = validator === 'matches';
@@ -15,13 +15,16 @@
15
15
 
16
16
  'use strict';
17
17
  const {
18
- DataflowTag: { UNTRUSTED }
18
+ DataflowTag: { UNTRUSTED },
19
+ join,
20
+ Rule,
21
+ isString,
22
+ inspect,
19
23
  } = require('@contrast/common');
20
24
 
21
25
  const { patchType } = require('../common');
22
- const { Rule, isString, inspect } = require('@contrast/common');
23
26
 
24
- module.exports = function (core) {
27
+ module.exports = function(core) {
25
28
  const {
26
29
  depHooks,
27
30
  patcher,
@@ -37,38 +40,53 @@ module.exports = function (core) {
37
40
 
38
41
  const safeTags = [];
39
42
 
40
- function commandCheck(name, command, secondArg, thirdArg, hooked) {
43
+ function commandCheck(
44
+ name,
45
+ method,
46
+ command,
47
+ secondArg,
48
+ thirdArg,
49
+ hooked,
50
+ orig
51
+ ) {
41
52
  const strInfo = tracker.getData(command);
42
- if (!strInfo || !isVulnerable(UNTRUSTED, safeTags, strInfo.tags)) return {
43
- strInfo: null,
44
- reported: false
45
- };
53
+ if (!strInfo || !isVulnerable(UNTRUSTED, safeTags, strInfo.tags))
54
+ return {
55
+ strInfo: null,
56
+ reported: false,
57
+ };
58
+
59
+ const args = [
60
+ {
61
+ value: strInfo.value,
62
+ tracked: true,
63
+ },
64
+ secondArg && {
65
+ value: inspect(secondArg),
66
+ tracked: false,
67
+ },
68
+ thirdArg && {
69
+ value: inspect(thirdArg),
70
+ tracked: false,
71
+ },
72
+ ].filter(Boolean);
46
73
 
47
74
  const event = createSinkEvent({
48
75
  name,
76
+ moduleName: 'child_process',
77
+ methodName: method,
78
+ context: `child_process.${method}(${join(args.map((a, idx) => idx === 0 ? `'${a.value}'` : a.value), ', ')})`,
49
79
  history: [strInfo],
50
80
  object: {
51
81
  value: 'child_process',
52
82
  tracked: false,
53
83
  },
54
- args: [
55
- {
56
- value: strInfo.value,
57
- tracked: true,
58
- },
59
- (secondArg && {
60
- value: inspect(secondArg),
61
- tracked: false
62
- }),
63
- (thirdArg && {
64
- value: inspect(thirdArg),
65
- tracked: false
66
- })
67
- ].filter(Boolean),
84
+ args,
68
85
  tags: strInfo.tags,
69
86
  source: 'P0',
70
87
  stacktraceOpts: {
71
88
  constructorOpt: hooked,
89
+ prependFrames: [orig],
72
90
  },
73
91
  });
74
92
 
@@ -80,24 +98,33 @@ module.exports = function (core) {
80
98
 
81
99
  return {
82
100
  strInfo,
83
- reported: true
101
+ reported: true,
84
102
  };
85
103
  }
86
104
 
87
105
  return {
88
106
  strInfo,
89
- reported: false
107
+ reported: false,
90
108
  };
91
109
  }
92
110
 
93
- function argumentsCheck(name, command, commandInfo, args, options, hooked) {
94
- if (!Array.isArray(args) || !args?.length) return;
111
+ function argumentsCheck(
112
+ name,
113
+ method,
114
+ command,
115
+ commandInfo,
116
+ origArgs,
117
+ options,
118
+ hooked,
119
+ orig
120
+ ) {
121
+ if (!Array.isArray(origArgs) || !origArgs?.length) return;
95
122
 
96
123
  const trackedArgs = [];
97
124
  let vulnerableArgIdx;
98
125
 
99
- for (let i = 0; i < args.length; i++) {
100
- const trackData = tracker.getData(args[i]);
126
+ for (let i = 0; i < origArgs.length; i++) {
127
+ const trackData = tracker.getData(origArgs[i]);
101
128
 
102
129
  trackedArgs.push(trackData);
103
130
 
@@ -116,31 +143,36 @@ module.exports = function (core) {
116
143
 
117
144
  if (vulnerableArgIdx != 0 && !vulnerableArgIdx) return;
118
145
 
146
+ const args = [
147
+ {
148
+ value: commandInfo?.value || command,
149
+ tracked: !!commandInfo,
150
+ },
151
+ {
152
+ value: inspect(origArgs),
153
+ tracked: true,
154
+ },
155
+ {
156
+ value: inspect(options),
157
+ tracked: false,
158
+ },
159
+ ];
119
160
  const event = createSinkEvent({
120
161
  name,
162
+ moduleName: 'child_process',
163
+ methodName: method,
164
+ context: `child_process.${method}(${join(args.map((a, idx) => idx === 0 ? `'${a.value}'` : a.value), ', ')})`,
121
165
  history: [trackedArgs[vulnerableArgIdx]],
122
166
  object: {
123
167
  value: 'child_process',
124
168
  tracked: false,
125
169
  },
126
- args: [
127
- {
128
- value: commandInfo?.value || command,
129
- tracked: !!commandInfo,
130
- },
131
- {
132
- value: inspect(args),
133
- tracked: true
134
- },
135
- {
136
- value: inspect(options),
137
- tracked: false
138
- }
139
- ],
170
+ args,
140
171
  tags: trackedArgs[vulnerableArgIdx].tags,
141
172
  source: 'P1',
142
173
  stacktraceOpts: {
143
174
  contructorOpt: hooked,
175
+ prependFrames: [orig],
144
176
  },
145
177
  });
146
178
 
@@ -154,7 +186,7 @@ module.exports = function (core) {
154
186
 
155
187
  core.assess.dataflow.sinks.cmdInjection = {
156
188
  install() {
157
- depHooks.resolve({ name: 'child_process' }, cp => {
189
+ depHooks.resolve({ name: 'child_process' }, (cp) => {
158
190
  ['spawn', 'spawnSync'].forEach((method) => {
159
191
  const name = `child_process.${method}`;
160
192
  patcher.patch(cp, method, {
@@ -169,12 +201,29 @@ module.exports = function (core) {
169
201
  const cpArgs = Array.isArray(data.args[1]) && data.args[1];
170
202
  const options = cpArgs ? data.args[2] : data.args[1];
171
203
 
172
- const cmdCheck = commandCheck(name, command, cpArgs, options, data.hooked);
204
+ const cmdCheck = commandCheck(
205
+ name,
206
+ method,
207
+ command,
208
+ cpArgs,
209
+ options,
210
+ data.hooked,
211
+ data.orig
212
+ );
173
213
 
174
214
  if (cmdCheck.reported || !options?.shell) return;
175
215
 
176
- argumentsCheck(name, command, cmdCheck.strInfo, cpArgs, options, data.hooked);
177
- }
216
+ argumentsCheck(
217
+ name,
218
+ method,
219
+ command,
220
+ cmdCheck.strInfo,
221
+ cpArgs,
222
+ options,
223
+ data.hooked,
224
+ data.orig
225
+ );
226
+ },
178
227
  });
179
228
  });
180
229
 
@@ -189,8 +238,16 @@ module.exports = function (core) {
189
238
 
190
239
  if (!store || !command || !isString(command)) return;
191
240
 
192
- commandCheck(name, command, secondArg, thirdArg, data.hooked);
193
- }
241
+ commandCheck(
242
+ name,
243
+ method,
244
+ command,
245
+ secondArg,
246
+ thirdArg,
247
+ data.hooked,
248
+ data.orig
249
+ );
250
+ },
194
251
  });
195
252
  });
196
253
 
@@ -212,8 +269,17 @@ module.exports = function (core) {
212
269
 
213
270
  const cmdInfo = tracker.getData(command);
214
271
 
215
- argumentsCheck(name, command, cmdInfo, cpArgs, options, data.hooked);
216
- }
272
+ argumentsCheck(
273
+ name,
274
+ method,
275
+ command,
276
+ cmdInfo,
277
+ cpArgs,
278
+ options,
279
+ data.hooked,
280
+ data.orig
281
+ );
282
+ },
217
283
  });
218
284
  });
219
285
  });
@@ -32,7 +32,7 @@ const { createSubsetTags } = require('../../../tag-utils');
32
32
 
33
33
  const ruleId = 'unvalidated-redirect';
34
34
 
35
- module.exports = function (core) {
35
+ module.exports = function(core) {
36
36
  const {
37
37
  depHooks,
38
38
  patcher,
@@ -59,7 +59,7 @@ module.exports = function (core) {
59
59
  URL_ENCODED,
60
60
  ];
61
61
 
62
- unvalidatedRedirect.install = function () {
62
+ unvalidatedRedirect.install = function() {
63
63
  depHooks.resolve({ name: 'express', file: 'lib/response' }, (Response) => {
64
64
  const name = 'Express.Response.location';
65
65
  patcher.patch(Response, 'location', {
@@ -92,7 +92,9 @@ module.exports = function (core) {
92
92
  }],
93
93
  context: `response.location(${inspect(strInfo.value)})`,
94
94
  history: [strInfo],
95
- name: 'Express.Response.location',
95
+ name,
96
+ moduleName: 'express',
97
+ methodName: 'Response.location',
96
98
  object: {
97
99
  tracked: false,
98
100
  value: 'Express.Response',
@@ -105,6 +107,7 @@ module.exports = function (core) {
105
107
  source: 'P0',
106
108
  stacktraceOpts: {
107
109
  constructorOpt: data.hooked,
110
+ prependFrames: [data.orig]
108
111
  },
109
112
  });
110
113
 
@@ -50,7 +50,7 @@ const getURLArgument = (args) => {
50
50
  };
51
51
  };
52
52
 
53
- module.exports = function (core) {
53
+ module.exports = function(core) {
54
54
  const {
55
55
  config,
56
56
  depHooks,
@@ -77,9 +77,9 @@ module.exports = function (core) {
77
77
  URL_ENCODED,
78
78
  ];
79
79
 
80
- unvalidatedRedirect.install = function () {
80
+ unvalidatedRedirect.install = function() {
81
81
  const name = 'fastify.Reply.prototype.redirect';
82
- depHooks.resolve({ name: 'fastify', file: 'lib/reply' }, (Reply, version) => {
82
+ depHooks.resolve({ name: 'fastify', file: 'lib/reply' }, (Reply) => {
83
83
  patcher.patch(Reply.prototype, 'redirect', {
84
84
  name,
85
85
  patchType,
@@ -119,7 +119,9 @@ module.exports = function (core) {
119
119
  args,
120
120
  context: `reply.redirect(${inspect(strInfo.value)})`,
121
121
  history: [strInfo],
122
- name: 'fastify.reply.redirect',
122
+ name,
123
+ moduleName: 'fastify',
124
+ methodName: 'reply.redirect',
123
125
  object: {
124
126
  tracked: false,
125
127
  value: 'fastify.Reply',
@@ -132,6 +134,7 @@ module.exports = function (core) {
132
134
  source: `P${valueIndex}`,
133
135
  stacktraceOpts: {
134
136
  constructorOpt: data.hooked,
137
+ prependFrames: [data.orig]
135
138
  },
136
139
  });
137
140
 
@@ -15,9 +15,22 @@
15
15
 
16
16
  'use strict';
17
17
  const { patchType } = require('../common');
18
- const { FS_METHODS, Rule, isString, DataflowTag: { URL_ENCODED, LIMITED_CHARS, ALPHANUM_SPACE_HYPHEN, SAFE_PATH, UNTRUSTED } } = require('@contrast/common');
18
+ const {
19
+ FS_METHODS,
20
+ Rule,
21
+ isString,
22
+ DataflowTag: {
23
+ URL_ENCODED,
24
+ LIMITED_CHARS,
25
+ ALPHANUM_SPACE_HYPHEN,
26
+ SAFE_PATH,
27
+ UNTRUSTED,
28
+ },
29
+ inspect,
30
+ join,
31
+ } = require('@contrast/common');
19
32
 
20
- module.exports = function (core) {
33
+ module.exports = function(core) {
21
34
  const {
22
35
  depHooks,
23
36
  patcher,
@@ -31,7 +44,12 @@ module.exports = function (core) {
31
44
  },
32
45
  } = core;
33
46
 
34
- const safeTags = [URL_ENCODED, LIMITED_CHARS, ALPHANUM_SPACE_HYPHEN, SAFE_PATH];
47
+ const safeTags = [
48
+ URL_ENCODED,
49
+ LIMITED_CHARS,
50
+ ALPHANUM_SPACE_HYPHEN,
51
+ SAFE_PATH,
52
+ ];
35
53
 
36
54
  function getValues(indices, args) {
37
55
  return indices.reduce((acc, idx) => {
@@ -41,33 +59,47 @@ module.exports = function (core) {
41
59
  }, []);
42
60
  }
43
61
 
44
- const pre = (name, indices) => (data) => {
62
+ const pre = (name, method, moduleName = 'fs', fullMethodName = '') => (data) => {
63
+ const { name: methodName, indices } = method;
45
64
  const store = sources.getStore()?.assess;
46
65
  if (!store) return;
47
66
 
48
67
  const values = getValues(indices, data.args);
49
68
  if (!values.length) return;
50
69
 
51
- const args = [];
70
+ const args = values.map((v) => {
71
+ const strInfo = tracker.getData(v);
72
+ return {
73
+ value: strInfo ? strInfo.value : v,
74
+ isTracked: !!strInfo,
75
+ strInfo
76
+ };
77
+ });
52
78
  for (let i = 0; i < values.length; i++) {
53
- const strInfo = tracker.getData(values[i]);
54
- args.push({ value: strInfo ? strInfo.value : values[i], isTracked: !!strInfo });
79
+ const { strInfo } = args[i];
55
80
  if (!strInfo || !isVulnerable(UNTRUSTED, safeTags, strInfo.tags)) {
56
81
  continue;
57
82
  }
58
83
 
59
84
  const event = createSinkEvent({
60
85
  name,
86
+ moduleName,
87
+ methodName: fullMethodName || methodName,
88
+ context: `${name}(${join(
89
+ args.map((a) => inspect(a.value)),
90
+ ', '
91
+ )})`,
61
92
  history: [strInfo],
62
93
  object: {
63
94
  value: 'fs',
64
95
  isTracked: false,
65
96
  },
66
- args,
97
+ args: args.map(({ value, isTracked }) => ({ value, isTracked })),
67
98
  tags: strInfo.tags,
68
99
  source: `P${i}`,
69
100
  stacktraceOpts: {
70
101
  contructorOpt: data.hooked,
102
+ prependFrames: [data.orig],
71
103
  },
72
104
  });
73
105
 
@@ -90,7 +122,7 @@ module.exports = function (core) {
90
122
  patcher.patch(fs, method.name, {
91
123
  name,
92
124
  patchType,
93
- pre: pre(name, method.indices)
125
+ pre: pre(name, method),
94
126
  });
95
127
  }
96
128
 
@@ -101,7 +133,7 @@ module.exports = function (core) {
101
133
  patcher.patch(fs, syncName, {
102
134
  name,
103
135
  patchType,
104
- pre: pre(name, method.indices)
136
+ pre: pre(name, method, 'fs', syncName),
105
137
  });
106
138
  }
107
139
  }
@@ -111,7 +143,7 @@ module.exports = function (core) {
111
143
  patcher.patch(fs.promises, method.name, {
112
144
  name,
113
145
  patchType,
114
- pre: pre(name, method.indices)
146
+ pre: pre(name, method, 'fs.promises'),
115
147
  });
116
148
  }
117
149
  }
@@ -124,7 +156,7 @@ module.exports = function (core) {
124
156
  patcher.patch(fsPromises, method.name, {
125
157
  name,
126
158
  patchType,
127
- pre: pre(name, method.indices)
159
+ pre: pre(name, method, 'fsPromises'),
128
160
  });
129
161
  }
130
162
  }
@@ -86,9 +86,11 @@ module.exports = function(core) {
86
86
  value: strInfo.value,
87
87
  tracked: true
88
88
  }],
89
- context: `res.${method}(${strInfo.value})`,
89
+ context: `res.${method}('${strInfo.value}')`,
90
90
  history: [strInfo],
91
91
  name,
92
+ moduleName: 'http',
93
+ methodName: `ServerResponse.prototype.${method}`,
92
94
  object: {
93
95
  tracked: false,
94
96
  value: 'http.ServerResponse'
@@ -99,7 +101,8 @@ module.exports = function(core) {
99
101
  },
100
102
  source: 'P0',
101
103
  stacktraceOpts: {
102
- constructorOpt: data.hooked
104
+ constructorOpt: data.hooked,
105
+ prependFrames: [data.orig]
103
106
  },
104
107
  tags: strInfo.tags,
105
108
  });
@@ -32,7 +32,7 @@ const { filterSafeTags, patchType } = require('../../common');
32
32
 
33
33
  const ruleId = 'unvalidated-redirect';
34
34
 
35
- module.exports = function (core) {
35
+ module.exports = function(core) {
36
36
  const {
37
37
  depHooks,
38
38
  patcher,
@@ -59,11 +59,11 @@ module.exports = function (core) {
59
59
  URL_ENCODED,
60
60
  ];
61
61
 
62
- unvalidatedRedirect.install = function () {
62
+ unvalidatedRedirect.install = function() {
63
63
  depHooks.resolve({ name: 'koa', file: 'lib/response', version: '<2.9.0' }, (Response) => {
64
64
  const name = 'Koa.Response.redirect';
65
65
  patcher.patch(Response, 'redirect', {
66
- name: 'Koa.Response.redirect',
66
+ name,
67
67
  patchType,
68
68
  pre(data) {
69
69
  const assessStore = sources.getStore()?.assess;
@@ -104,7 +104,9 @@ module.exports = function (core) {
104
104
  args,
105
105
  context: `response.redirect(${inspect(strInfo.value)})`,
106
106
  history: [strInfo],
107
- name: 'Koa.Response.redirect',
107
+ name,
108
+ moduleName: 'koa',
109
+ methodName: 'Response.redirect',
108
110
  object: {
109
111
  tracked: false,
110
112
  value: 'Koa.Response',
@@ -117,6 +119,7 @@ module.exports = function (core) {
117
119
  source: `P${isBackRoute ? 1 : 0}`,
118
120
  stacktraceOpts: {
119
121
  constructorOpt: data.hooked,
122
+ prependFrames: [data.orig]
120
123
  },
121
124
  });
122
125
 
@@ -102,6 +102,8 @@ module.exports = function(core) {
102
102
  const sinkEvent = createSinkEvent({
103
103
  args,
104
104
  context: `marsdb.Collection.${method}(${args.map((a) => a.value)})`,
105
+ moduleName: 'marsdb',
106
+ methodName: `Collection.prototype.${method}`,
105
107
  history: [strInfo],
106
108
  object: {
107
109
  tracked: false,
@@ -112,6 +114,7 @@ module.exports = function(core) {
112
114
  source: `P${argIdx}`,
113
115
  stacktraceOpts: {
114
116
  constructorOpt: data.hooked,
117
+ prependFrames: [data.orig]
115
118
  },
116
119
  tags: strInfo.tags,
117
120
  });
@@ -286,13 +286,15 @@ module.exports = function(core) {
286
286
  const resultVal = args[args.length - 1].value.startsWith('[Function') ? '' : 'Promise';
287
287
  const sinkEvent = createSinkEvent({
288
288
  args,
289
- context: `${objName}.${method}(${args.map((a) => a.value)})`,
289
+ context: `${objName}.${method}(${args.map((a, idx) => isString(origArgs[idx]) ? `'${a.value}'` : a.value)})`,
290
290
  history: [strInfo],
291
291
  object: {
292
292
  tracked: false,
293
293
  value: `mongodb.${entity}`,
294
294
  },
295
295
  name,
296
+ moduleName: 'mongodb',
297
+ methodName: `${entity}.prototype.${method}`,
296
298
  result: {
297
299
  tracked: false,
298
300
  value: resultVal,
@@ -30,7 +30,7 @@ const safeTags = [
30
30
  CUSTOM_ENCODED,
31
31
  ];
32
32
 
33
- module.exports = function (core) {
33
+ module.exports = function(core) {
34
34
  const {
35
35
  depHooks,
36
36
  patcher,
@@ -44,7 +44,7 @@ module.exports = function (core) {
44
44
  },
45
45
  } = core;
46
46
 
47
- const pre = (name, obj, version) => (data) => {
47
+ const pre = (name, method, obj, version) => (data) => {
48
48
  const store = sources.getStore()?.assess;
49
49
  if (
50
50
  !store ||
@@ -60,6 +60,9 @@ module.exports = function (core) {
60
60
 
61
61
  const event = createSinkEvent({
62
62
  name,
63
+ moduleName: 'mssql',
64
+ methodName: `PreparedStatement.prototype.${method}`,
65
+ context: `mssql.PreparedStatement.${method}('${strInfo.value}')`,
63
66
  history: [strInfo],
64
67
  object: {
65
68
  value: `[${createModuleLabel('mssql', version)}].${obj}`,
@@ -75,6 +78,7 @@ module.exports = function (core) {
75
78
  source: 'P0',
76
79
  stacktraceOpts: {
77
80
  contructorOpt: data.hooked,
81
+ prependFrames: [data.orig]
78
82
  },
79
83
  });
80
84
 
@@ -96,6 +100,7 @@ module.exports = function (core) {
96
100
  patchType,
97
101
  pre: pre(
98
102
  'mssql/lib/base/prepared-statement.prototype.prepare',
103
+ 'prepare',
99
104
  'PreparedStatement',
100
105
  version,
101
106
  ),
@@ -111,6 +116,7 @@ module.exports = function (core) {
111
116
  patchType,
112
117
  pre: pre(
113
118
  'mssql/lib/base/request.prototype.batch',
119
+ 'batch',
114
120
  'Request',
115
121
  version,
116
122
  ),
@@ -121,6 +127,7 @@ module.exports = function (core) {
121
127
  patchType,
122
128
  pre: pre(
123
129
  'mssql/lib/base/request.prototype.query',
130
+ 'query',
124
131
  'Request',
125
132
  version,
126
133
  ),