@contrast/protect 1.49.0 → 1.50.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/error-handlers/index.js +1 -1
  2. package/lib/error-handlers/index.test.js +1 -1
  3. package/lib/error-handlers/install/express.js +162 -0
  4. package/lib/error-handlers/install/express.test.js +290 -0
  5. package/lib/error-handlers/install/hapi.js +2 -2
  6. package/lib/error-handlers/install/hapi.test.js +2 -2
  7. package/lib/error-handlers/install/koa2.js +1 -1
  8. package/lib/error-handlers/install/restify.js +1 -1
  9. package/lib/error-handlers/install/restify.test.js +1 -1
  10. package/lib/hardening/install/node-serialize0.js +2 -2
  11. package/lib/hardening/install/node-serialize0.test.js +1 -4
  12. package/lib/index.d.ts +1 -1
  13. package/lib/input-analysis/index.js +1 -1
  14. package/lib/input-analysis/index.test.js +1 -1
  15. package/lib/input-analysis/install/body-parser1.js +2 -2
  16. package/lib/input-analysis/install/busboy1.js +1 -1
  17. package/lib/input-analysis/install/cookie-parser1.js +1 -1
  18. package/lib/input-analysis/install/{express4.js → express.js} +61 -20
  19. package/lib/input-analysis/install/{express4.test.js → express.test.js} +92 -59
  20. package/lib/input-analysis/install/formidable1.js +1 -1
  21. package/lib/input-analysis/install/hapi.js +1 -1
  22. package/lib/input-analysis/install/hapi.test.js +6 -14
  23. package/lib/input-analysis/install/koa-body5.js +1 -1
  24. package/lib/input-analysis/install/koa-bodyparser4.js +1 -1
  25. package/lib/input-analysis/install/koa2.js +5 -5
  26. package/lib/input-analysis/install/multer1.js +1 -1
  27. package/lib/input-analysis/install/qs6.js +1 -1
  28. package/lib/input-analysis/install/restify.js +1 -1
  29. package/lib/input-analysis/install/restify.test.js +1 -1
  30. package/lib/input-analysis/install/universal-cookie4.js +1 -1
  31. package/lib/input-tracing/install/child-process.js +1 -1
  32. package/lib/input-tracing/install/fs.js +2 -2
  33. package/lib/input-tracing/install/fs.test.js +2 -2
  34. package/lib/input-tracing/install/http.js +2 -2
  35. package/lib/input-tracing/install/http2.js +2 -2
  36. package/lib/input-tracing/install/marsdb.js +2 -2
  37. package/lib/input-tracing/install/marsdb.test.js +1 -1
  38. package/lib/input-tracing/install/mongodb.js +2 -2
  39. package/lib/input-tracing/install/mongodb.test.js +2 -4
  40. package/lib/input-tracing/install/mssql.js +3 -3
  41. package/lib/input-tracing/install/mssql.test.js +2 -2
  42. package/lib/input-tracing/install/mysql.js +7 -9
  43. package/lib/input-tracing/install/postgres.js +3 -3
  44. package/lib/input-tracing/install/postgres.test.js +2 -10
  45. package/lib/input-tracing/install/sequelize.js +2 -2
  46. package/lib/input-tracing/install/spdy.js +2 -2
  47. package/lib/input-tracing/install/sqlite3.js +2 -2
  48. package/lib/input-tracing/install/vm.js +2 -2
  49. package/lib/semantic-analysis/install/libxmljs.js +3 -3
  50. package/lib/semantic-analysis/install/libxmljs.test.js +2 -2
  51. package/package.json +11 -11
  52. package/lib/error-handlers/install/express4.js +0 -138
  53. package/lib/error-handlers/install/express4.test.js +0 -238
@@ -32,12 +32,34 @@ module.exports = (core) => {
32
32
  protect: { inputAnalysis },
33
33
  } = core;
34
34
 
35
+ function layerPostHook(name) {
36
+ return function(data) {
37
+ const layer = data.obj;
38
+
39
+ // we can exit early if
40
+ // the layer doesn't match the request or
41
+ // the layer doesn't recognize any parameters
42
+ if (!data.result || !layer.keys || layer.keys.length === 0 || layer.route?.path === '*') {
43
+ return;
44
+ }
45
+
46
+ const sourceContext = protect.getSourceContext(name);
47
+
48
+ if (!sourceContext) {
49
+ return;
50
+ }
51
+
52
+ sourceContext.parsedParams = layer.params;
53
+ inputAnalysis.handleUrlParams(sourceContext, layer.params);
54
+ };
55
+ }
56
+
35
57
  /**
36
58
  * registers a depHook for express module instrumentation
37
59
  */
38
60
  function install() {
39
61
  depHooks.resolve(
40
- { name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/middleware/query.js' },
62
+ { name: 'express', version: '4', file: 'lib/middleware/query.js' },
41
63
  (query) => patcher.patch(query, {
42
64
  name: 'express.query',
43
65
  patchType,
@@ -84,40 +106,59 @@ module.exports = (core) => {
84
106
  }));
85
107
 
86
108
  depHooks.resolve(
87
- { name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/router/layer.js' },
109
+ { name: 'express', version: '4', file: 'lib/router/layer.js' },
88
110
  (Layer) => {
89
111
  const name = 'express.Layer.prototype.match';
90
112
  patcher.patch(Layer.prototype, 'match', {
91
113
  name,
92
114
  patchType,
93
- post(data) {
94
- const layer = data.obj;
95
-
96
- // we can exit early if
97
- // the layer doesn't match the request or
98
- // the layer doesn't recognize any parameters
99
- if (!data.result || !layer.keys || layer.keys.length === 0 || layer.route?.path === '*') {
100
- return;
101
- }
115
+ post: layerPostHook(name)
116
+ });
102
117
 
103
- const sourceContext = protect.getSourceContext(name);
118
+ return Layer;
119
+ });
104
120
 
105
- if (!sourceContext) {
106
- return;
121
+ depHooks.resolve(
122
+ { name: 'express', version: '5', file: 'lib/request.js' },
123
+ (request) => {
124
+ const { get } = Object.getOwnPropertyDescriptor(request, 'query');
125
+ const patchedGet = patcher.patch(get, {
126
+ name: 'request.query.get',
127
+ patchType,
128
+ post(data) {
129
+ const query = data.result;
130
+ if (query && Object.keys(query).length) {
131
+ const sourceContext = protect.getSourceContext();
132
+ if (sourceContext && !('parsedQuery' in sourceContext)) {
133
+ sourceContext.parsedQuery = query;
134
+ inputAnalysis.handleQueryParams(sourceContext, query);
135
+ }
107
136
  }
108
-
109
- sourceContext.parsedParams = layer.params;
110
- inputAnalysis.handleUrlParams(sourceContext, layer.params);
111
137
  }
112
138
  });
139
+ Object.defineProperty(request, 'query', {
140
+ get: patchedGet
141
+ });
142
+ }
143
+ );
113
144
 
145
+ depHooks.resolve(
146
+ { name: 'router', version: '2', file: 'lib/layer.js' },
147
+ (Layer) => {
148
+ const name = 'Layer.prototype.match';
149
+ patcher.patch(Layer.prototype, 'match', {
150
+ name,
151
+ patchType,
152
+ post: layerPostHook(name)
153
+ });
114
154
  return Layer;
115
- });
155
+ }
156
+ );
116
157
  }
117
158
 
118
- const express4Instrumentation = inputAnalysis.express4Instrumentation = {
159
+ const expressInstrumentation = inputAnalysis.expressInstrumentation = {
119
160
  install
120
161
  };
121
162
 
122
- return express4Instrumentation;
163
+ return expressInstrumentation;
123
164
  };
@@ -7,12 +7,13 @@ const patcher = require('@contrast/patcher');
7
7
  const mocks = require('@contrast/test/mocks');
8
8
  const SecurityException = require('../../security-exception');
9
9
  const secEx = SecurityException.create();
10
- const expressInstr = require('./express4');
10
+ const expressInstr = require('./express');
11
11
 
12
- describe('protect input-analysis express v4.x', function () {
12
+ describe('protect input-analysis express', function () {
13
13
  let core,
14
14
  inputAnalysis,
15
15
  expressQueryMock,
16
+ requestMock,
16
17
  nextStub,
17
18
  query,
18
19
  Layer;
@@ -33,11 +34,17 @@ describe('protect input-analysis express v4.x', function () {
33
34
  next();
34
35
  };
35
36
 
37
+ requestMock = {
38
+ get query() {
39
+ return { parameter: 'parsed-query' };
40
+ }
41
+ };
42
+
36
43
  Layer = sinon.stub();
37
44
  Layer.prototype.match = sinon.stub().returns(true);
38
45
 
39
- core.depHooks.resolve.withArgs({ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/middleware/query.js' }).yields(expressQueryMock);
40
- core.depHooks.resolve.withArgs({ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/router/layer.js' }).yields(Layer);
46
+ core.depHooks.resolve.withArgs({ name: 'express', version: '4', file: 'lib/middleware/query.js' }).yields(expressQueryMock);
47
+ core.depHooks.resolve.withArgs({ name: 'express', version: '5', file: 'lib/request.js' }).yields(requestMock);
41
48
 
42
49
  nextStub = sinon.stub();
43
50
 
@@ -47,22 +54,7 @@ describe('protect input-analysis express v4.x', function () {
47
54
  core.patcher.patch.resetHistory();
48
55
  });
49
56
 
50
- it('calls patcher for every necessary instrumentation', function () {
51
- expressInstr(core).install();
52
- expect(core.patcher.patch).to.have.callCount(2);
53
- expect(core.patcher.patch).to.have.been.calledWithMatch(expressQueryMock, {
54
- name: 'express.query',
55
- patchType: 'protect-input-analysis',
56
- post: sinon.match.func
57
- });
58
- expect(core.patcher.patch).to.have.been.calledWithMatch(Layer.prototype, 'match', {
59
- name: 'express.Layer.prototype.match',
60
- patchType: 'protect-input-analysis',
61
- post: sinon.match.func
62
- });
63
- });
64
-
65
- describe('express.query patch', function () {
57
+ describe('express4 query patch', function () {
66
58
  it('calls `.handleQueryParams` when parsing is successful and in right context', function () {
67
59
  core.scopes.sources.run({ protect: {} }, () => {
68
60
  const queryParser = expressQueryMock(query);
@@ -98,7 +90,6 @@ describe('protect input-analysis express v4.x', function () {
98
90
  });
99
91
 
100
92
  expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
101
- expect(core.logger.debug).not.to.have.been.called;
102
93
  expect(nextStub).to.have.been.calledOnce;
103
94
  });
104
95
 
@@ -109,7 +100,6 @@ describe('protect input-analysis express v4.x', function () {
109
100
  });
110
101
 
111
102
  expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
112
- expect(core.logger.debug).not.to.have.been.called;
113
103
  expect(nextStub).to.have.been.calledOnce;
114
104
  });
115
105
 
@@ -141,68 +131,111 @@ describe('protect input-analysis express v4.x', function () {
141
131
  });
142
132
  });
143
133
 
144
- describe('express.Layer.prototype.match patch', function () {
145
- let layer;
134
+ describe('express5 query get patch', function() {
135
+ it('does not call `.handleQueryParams` when not in context', function () {
136
+ core.scopes.sources.run({}, () => {
137
+ requestMock.query;
138
+ });
146
139
 
147
- beforeEach(function () {
148
- layer = { keys: ['foo'], params: { foo: 'bar' }, route: { path: '/test' } };
140
+ expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
149
141
  });
150
142
 
151
- it('calls `.handleUrlParams` when parsing is successful and in right context', function () {
143
+ it('does not call `.handleQueryParams` when no query exists', function () {
144
+ requestMock = {
145
+ get query() {
146
+ return {};
147
+ }
148
+ };
152
149
  core.scopes.sources.run({ protect: {} }, () => {
153
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
150
+ requestMock.query;
154
151
  });
155
152
 
156
- expect(inputAnalysis.handleUrlParams).to.have.been.calledOnce;
157
- expect(inputAnalysis.handleUrlParams).to.have.been.calledWithMatch({ parsedParams: layer.params }, layer.params);
153
+ expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
158
154
  });
159
155
 
160
- it('does not call `.handleUrlParams` when match returns false', function () {
161
- Layer.prototype.match.returns(false);
162
-
163
- core.scopes.sources.run({}, () => {
164
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
156
+ it('does not call `.handleQueryParams` when query was already parsed', function () {
157
+ core.scopes.sources.run({ protect: { parsedQuery: query } }, () => {
158
+ requestMock.query;
165
159
  });
166
160
 
167
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
168
- expect(core.logger.debug).not.to.have.been.called;
161
+ expect(inputAnalysis.handleQueryParams).not.to.have.been.called;
169
162
  });
170
163
 
171
- it('does not call `.handleUrlParams` when the route path is undefined', function () {
172
- core.scopes.sources.run({}, () => {
173
- Reflect.apply(Layer.prototype.match, { ...layer, route: undefined }, ['/bar']);
164
+ it('calls `.handleQueryParams` when parsing is successful and in right context', function () {
165
+ core.scopes.sources.run({ protect: {} }, () => {
166
+ requestMock.query;
174
167
  });
175
168
 
176
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
177
- expect(core.logger.debug).not.to.have.been.called;
169
+ expect(inputAnalysis.handleQueryParams).to.have.been.calledOnce;
170
+ expect(inputAnalysis.handleQueryParams).to.have.been.calledWithMatch({ parsedQuery: query }, query);
178
171
  });
172
+ });
179
173
 
180
- it('does not call `.handleUrlParams` when the route path is `*`', function () {
181
- core.scopes.sources.run({}, () => {
182
- Reflect.apply(Layer.prototype.match, { ...layer, route: { path: '*' } }, ['/bar']);
174
+ ['4', '5'].forEach((v) => {
175
+ describe(`express${v} Layer.prototype.match`, function() {
176
+ let layer;
177
+ beforeEach(function() {
178
+ const args = v === '4'
179
+ ? { name: 'express', version: '4', file: 'lib/router/layer.js' }
180
+ : { name: 'router', version: '2', file: 'lib/layer.js' };
181
+ core.depHooks.resolve.withArgs(args).yields(Layer);
182
+ expressInstr(core).install();
183
+ layer = { keys: ['foo'], params: { foo: 'bar' }, route: { path: '/test' } };
183
184
  });
184
185
 
185
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
186
- expect(core.logger.debug).not.to.have.been.called;
187
- });
186
+ it('calls `.handleUrlParams` when parsing is successful and in right context', function () {
187
+ core.scopes.sources.run({ protect: {} }, () => {
188
+ Reflect.apply(Layer.prototype.match, layer, ['/bar']);
189
+ });
188
190
 
189
- it('does not call `.handleUrlParams` when not in context', function () {
190
- core.scopes.sources.run({}, () => {
191
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
191
+ expect(inputAnalysis.handleUrlParams).to.have.been.calledOnce;
192
+ expect(inputAnalysis.handleUrlParams).to.have.been.calledWithMatch({ parsedParams: layer.params }, layer.params);
192
193
  });
193
194
 
194
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
195
- });
195
+ it('does not call `.handleUrlParams` when match returns false', function () {
196
+ Layer.prototype.match.returns(false);
196
197
 
197
- it('does not call `.handleUrlParams` when no params are present on the current layer', function () {
198
- layer = { keys: [], params: {} };
198
+ core.scopes.sources.run({}, () => {
199
+ Reflect.apply(Layer.prototype.match, layer, ['/bar']);
200
+ });
199
201
 
200
- core.scopes.sources.run({ protect: {} }, () => {
201
- Reflect.apply(Layer.prototype.match, layer, ['/bar']);
202
+ expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
203
+ });
204
+
205
+ it('does not call `.handleUrlParams` when the route path is undefined', function () {
206
+ core.scopes.sources.run({}, () => {
207
+ Reflect.apply(Layer.prototype.match, { ...layer, route: undefined }, ['/bar']);
208
+ });
209
+
210
+ expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
211
+ });
212
+
213
+ it('does not call `.handleUrlParams` when the route path is `*`', function () {
214
+ core.scopes.sources.run({}, () => {
215
+ Reflect.apply(Layer.prototype.match, { ...layer, route: { path: '*' } }, ['/bar']);
216
+ });
217
+
218
+ expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
219
+ });
220
+
221
+ it('does not call `.handleUrlParams` when not in context', function () {
222
+ core.scopes.sources.run({}, () => {
223
+ Reflect.apply(Layer.prototype.match, layer, ['/bar']);
224
+ });
225
+
226
+ expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
227
+ });
228
+
229
+ it('does not call `.handleUrlParams` when no params are present on the current layer', function () {
230
+ layer = { keys: [], params: {} };
231
+
232
+ core.scopes.sources.run({ protect: {} }, () => {
233
+ Reflect.apply(Layer.prototype.match, layer, ['/bar']);
234
+ });
235
+
236
+ expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
202
237
  });
203
238
 
204
- expect(inputAnalysis.handleUrlParams).not.to.have.been.called;
205
- expect(core.logger.debug).not.to.have.been.called;
206
239
  });
207
240
  });
208
241
  });
@@ -27,7 +27,7 @@ module.exports = (core) => {
27
27
 
28
28
  // Patch `formidable`
29
29
  function install() {
30
- depHooks.resolve({ name: 'formidable' }, (formidable) => {
30
+ depHooks.resolve({ name: 'formidable', version: '<4' }, (formidable) => {
31
31
  formidable.IncomingForm.prototype.parse = patcher.patch(formidable.IncomingForm.prototype.parse, {
32
32
  name: 'Formidable.IncomingForm.prototype.parse',
33
33
  patchType,
@@ -40,7 +40,7 @@ module.exports = (core) => {
40
40
  registerServerHandler
41
41
  );
42
42
  depHooks.resolve(
43
- { name: '@hapi/pez' },
43
+ { name: '@hapi/pez', version: '<7' },
44
44
  registerMultipartHandler
45
45
  );
46
46
  }
@@ -13,17 +13,9 @@ describe('protect input-analysis hapi', function () {
13
13
  store,
14
14
  inputAnalysis;
15
15
 
16
- const Hapi = {
17
- name: 'hapi',
18
- version: '>=18 <22'
19
- };
20
- const HapiHapi = {
21
- name: '@hapi/hapi',
22
- version: '>=18 <22'
23
- };
24
- const HapiPez = {
25
- name: '@hapi/pez'
26
- };
16
+ const Hapi = { name: 'hapi' };
17
+ const HapiHapi = { name: '@hapi/hapi' };
18
+ const HapiPez = { name: '@hapi/pez' };
27
19
 
28
20
  beforeEach(function () {
29
21
  core = mocks.core();
@@ -53,9 +45,9 @@ describe('protect input-analysis hapi', function () {
53
45
  HapiPez.Dispenser = function () { };
54
46
  HapiPez.Dispenser.prototype.emit = function () { };
55
47
 
56
- core.depHooks.resolve.withArgs({ name: Hapi.name, version: Hapi.version }).yields(Hapi);
57
- core.depHooks.resolve.withArgs({ name: HapiHapi.name, version: HapiHapi.version }).yields(HapiHapi);
58
- core.depHooks.resolve.withArgs({ name: HapiPez.name }).yields(HapiPez);
48
+ core.depHooks.resolve.withArgs(sinon.match({ name: Hapi.name })).yields(Hapi);
49
+ core.depHooks.resolve.withArgs(sinon.match({ name: HapiHapi.name })).yields(HapiHapi);
50
+ core.depHooks.resolve.withArgs(sinon.match({ name: HapiPez.name })).yields(HapiPez);
59
51
 
60
52
  hapiSources = require('./hapi')(core);
61
53
  hapiSources.install();
@@ -27,7 +27,7 @@ module.exports = (core) => {
27
27
 
28
28
  // Patch `koa-body` package
29
29
  function install() {
30
- depHooks.resolve({ name: 'koa-body' }, (koaBody) => patcher.patch(koaBody, {
30
+ depHooks.resolve({ name: 'koa-body', version: '<7' }, (koaBody) => patcher.patch(koaBody, {
31
31
  name: 'koa-body',
32
32
  patchType,
33
33
  post(data) {
@@ -27,7 +27,7 @@ module.exports = (core) => {
27
27
 
28
28
  // Patch `koa-bodyparser` package
29
29
  function install() {
30
- depHooks.resolve({ name: 'koa-bodyparser' }, (koaBodyparser) => patcher.patch(koaBodyparser, {
30
+ depHooks.resolve({ name: 'koa-bodyparser', version: '<5' }, (koaBodyparser) => patcher.patch(koaBodyparser, {
31
31
  name: 'koa-bodyparser',
32
32
  patchType,
33
33
  post(data) {
@@ -34,7 +34,7 @@ module.exports = (core) => {
34
34
  * registers a depHook for koa module instrumentation
35
35
  */
36
36
  function install() {
37
- depHooks.resolve({ name: 'koa', version: '>=2.3.0' }, (Koa) => {
37
+ depHooks.resolve({ name: 'koa', version: '>=2.3.0 <3' }, (Koa) => {
38
38
  function contrastStartMiddleware(ctx, next) {
39
39
  if (ctx.query && Object.keys(ctx.query).length) {
40
40
  const sourceContext = protect.getSourceContext();
@@ -65,15 +65,15 @@ module.exports = (core) => {
65
65
  });
66
66
 
67
67
  // Patch `koa-router` and `@koa/router` to handle parsed params
68
- ['koa-router', '@koa/router'].forEach(router => {
68
+ [['koa-router', '<14'], ['@koa/router', '<14']].forEach(([router, version]) => {
69
69
  depHooks.resolve(
70
- { name: router, file: 'lib/layer.js' },
70
+ { name: router, version, file: 'lib/layer.js' },
71
71
  (layer) => {
72
72
  layer.prototype = patcher.patch(layer.prototype, 'params', {
73
73
  name: `[${router}].layer.prototype`,
74
74
  patchType,
75
75
  post({ result }) {
76
- const sourceContext = protect.getSourceContext(`[${router}].layer`);
76
+ const sourceContext = protect.getSourceContext();
77
77
 
78
78
  if (sourceContext && Object.keys(result).length) {
79
79
  sourceContext.parsedParams = result;
@@ -87,7 +87,7 @@ module.exports = (core) => {
87
87
  });
88
88
 
89
89
  // Patch `koa-cookie`
90
- depHooks.resolve({ name: 'koa-cookie' }, (koaCookie) => {
90
+ depHooks.resolve({ name: 'koa-cookie', version: '<2' }, (koaCookie) => {
91
91
  const { default: cookieParser } = koaCookie;
92
92
  koaCookie.default = patcher.patch(cookieParser, {
93
93
  name: 'koa-cookie',
@@ -30,7 +30,7 @@ module.exports = (core) => {
30
30
 
31
31
  // Patch `multer`
32
32
  function install() {
33
- depHooks.resolve({ name: 'multer', file: 'lib/make-middleware.js' }, (multerMakeMiddleware) => patcher.patch(multerMakeMiddleware, {
33
+ depHooks.resolve({ name: 'multer', version: '<2', file: 'lib/make-middleware.js' }, (multerMakeMiddleware) => patcher.patch(multerMakeMiddleware, {
34
34
  name: 'multer.make-middleware',
35
35
  patchType,
36
36
  post(data) {
@@ -27,7 +27,7 @@ module.exports = (core) => {
27
27
 
28
28
  // Patch `qs`
29
29
  function install() {
30
- depHooks.resolve({ name: 'qs' },
30
+ depHooks.resolve({ name: 'qs', version: '<7' },
31
31
  (qs) => patcher.patch(qs, 'parse', {
32
32
  name: 'qs',
33
33
  patchType,
@@ -25,7 +25,7 @@ module.exports = function init(core) {
25
25
  return inputAnalysis.restifyInstrumentation = {
26
26
  install() {
27
27
  depHooks.resolve(
28
- { name: 'restify', file: 'lib/server.js', version: '>=8' },
28
+ { name: 'restify', file: 'lib/server.js', version: '>=8 <12' },
29
29
  (Server) => {
30
30
  patcher.patch(Server.prototype, '_afterUse', {
31
31
  name: 'restify.Server.prototype._afterUse',
@@ -22,7 +22,7 @@ describe('protect input-analysis restify v8+', function () {
22
22
  req = {};
23
23
 
24
24
  core.depHooks.resolve
25
- .withArgs({ name: 'restify', file: 'lib/server.js', version: '>=8' })
25
+ .withArgs({ name: 'restify', file: 'lib/server.js', version: '>=8 <12' })
26
26
  .yields(Server);
27
27
 
28
28
  inputAnalysis.restifyInstrumentation.install();
@@ -27,7 +27,7 @@ module.exports = (core) => {
27
27
 
28
28
  // Patch `universal-cookie` package
29
29
  function install() {
30
- depHooks.resolve({ name: 'universal-cookie', file: 'cjs/utils.js' }, (uCookieUtils) => patcher.patch(uCookieUtils, 'parseCookies', {
30
+ depHooks.resolve({ name: 'universal-cookie', version: '<8', file: 'cjs/utils.js' }, (uCookieUtils) => patcher.patch(uCookieUtils, 'parseCookies', {
31
31
  name: 'universal-cookie.utils',
32
32
  patchType,
33
33
  post({ result }) {
@@ -49,7 +49,7 @@ module.exports = function (core) {
49
49
 
50
50
 
51
51
  function install() {
52
- depHooks.resolve({ name: 'child_process' }, cp => {
52
+ depHooks.resolve({ name: 'child_process', version: '*' }, cp => {
53
53
  ['exec', 'execSync'].forEach((method) => {
54
54
  const name = `child_process.${method}`;
55
55
  patcher.patch(cp, method, {
@@ -65,7 +65,7 @@ module.exports = function init(core) {
65
65
 
66
66
  return core.protect.inputTracing.fsInstrumentation = {
67
67
  install() {
68
- depHooks.resolve({ name: 'fs' }, (fs) => {
68
+ depHooks.resolve({ name: 'fs', version: '*' }, (fs) => {
69
69
  for (const method of FS_METHODS) {
70
70
  // not all methods are available on every OS or Node version.
71
71
  if (fs[method.name]) {
@@ -97,7 +97,7 @@ module.exports = function init(core) {
97
97
  }
98
98
  });
99
99
 
100
- depHooks.resolve({ name: 'fs/promises' }, (fsPromises) => {
100
+ depHooks.resolve({ name: 'fs/promises', version: '*' }, (fsPromises) => {
101
101
  for (const method of FS_METHODS) {
102
102
  if (method.promises && fsPromises[method.name]) {
103
103
  patcher.patch(fsPromises, method.name, {
@@ -30,8 +30,8 @@ describe('protect input-tracing fs', function () {
30
30
  core = mocks.core();
31
31
  core.logger = mocks.logger();
32
32
  core.depHooks = mocks.depHooks();
33
- core.depHooks.resolve.withArgs({ name: 'fs' }).yields(fs);
34
- core.depHooks.resolve.withArgs({ name: 'fs/promises' }).yields(fsPromises);
33
+ core.depHooks.resolve.withArgs(sinon.match({ name: 'fs' })).yields(fs);
34
+ core.depHooks.resolve.withArgs(sinon.match({ name: 'fs/promises' })).yields(fsPromises);
35
35
  core.scopes = mocks.scopes();
36
36
  sinon.stub(core.scopes.sources, 'getStore').returns(store);
37
37
  core.patcher = patcher(core);
@@ -27,7 +27,7 @@ module.exports = function(core) {
27
27
  } = core;
28
28
 
29
29
  function install() {
30
- depHooks.resolve({ name: 'http' }, http => {
30
+ depHooks.resolve({ name: 'http', version: '*' }, http => {
31
31
  for (const method of ['write', 'end']) {
32
32
  const name = `http.ServerResponse.prototype.${method}`;
33
33
  patcher.patch(http.ServerResponse.prototype, method, {
@@ -36,7 +36,7 @@ module.exports = function(core) {
36
36
  pre(data) {
37
37
  if (instrumentation.isLocked()) return;
38
38
 
39
- const sourceContext = protect.getSourceContext(name);
39
+ const sourceContext = protect.getSourceContext();
40
40
  if (!sourceContext) return;
41
41
 
42
42
  const value = data.args[0]?.toString?.();
@@ -27,7 +27,7 @@ module.exports = function(core) {
27
27
  } = core;
28
28
 
29
29
  function install() {
30
- depHooks.resolve({ name: 'http2' }, http2 => {
30
+ depHooks.resolve({ name: 'http2', version: '*' }, http2 => {
31
31
  for (const method of ['write', 'end']) {
32
32
  const name = `http2.Http2ServerResponse.prototype.${method}`;
33
33
  patcher.patch(http2.Http2ServerResponse.prototype, method, {
@@ -36,7 +36,7 @@ module.exports = function(core) {
36
36
  pre(data) {
37
37
  if (instrumentation.isLocked()) return;
38
38
 
39
- const sourceContext = protect.getSourceContext(name);
39
+ const sourceContext = protect.getSourceContext();
40
40
 
41
41
  if (!sourceContext) return;
42
42
 
@@ -43,7 +43,7 @@ module.exports = function(core) {
43
43
  }
44
44
 
45
45
  function install() {
46
- depHooks.resolve({ name: 'marsdb' }, marsdb => {
46
+ depHooks.resolve({ name: 'marsdb', version: '<1' }, marsdb => {
47
47
  methods.forEach((method) => {
48
48
  const name = `marsdb.Collection.prototype.${method}`;
49
49
 
@@ -52,7 +52,7 @@ module.exports = function(core) {
52
52
  patchType,
53
53
  pre({ args, hooked, orig }) {
54
54
  const value = getCursorQueryData(args);
55
- const sourceContext = getSourceContext(name);
55
+ const sourceContext = getSourceContext();
56
56
 
57
57
  if (
58
58
  !sourceContext ||
@@ -34,7 +34,7 @@ describe('protect input-tracing marsdb', function () {
34
34
  mockMarsDb.Collection.prototype[method] = () => { };
35
35
  });
36
36
 
37
- core.depHooks.resolve.withArgs({ name: 'marsdb' }).yields(mockMarsDb);
37
+ core.depHooks.resolve.yields(mockMarsDb);
38
38
 
39
39
  marsdbInstr = require('./marsdb')(core);
40
40
  });
@@ -142,7 +142,7 @@ module.exports = function(core) {
142
142
  const argsIdxsToCheck = vulnerableArgIdxs || [0];
143
143
  return function(next, data) {
144
144
  const { args, name, hooked, orig } = data;
145
- const sourceCtx = getSourceContext(name);
145
+ const sourceCtx = getSourceContext();
146
146
 
147
147
  if (instrumentation.isLocked() || !sourceCtx) {
148
148
  return next();
@@ -158,7 +158,7 @@ module.exports = function(core) {
158
158
  }
159
159
 
160
160
  instr.install = function() {
161
- depHooks.resolve({ name: 'mongodb' }, (mongodb, version) => {
161
+ depHooks.resolve({ name: 'mongodb', version: '<7' }, (mongodb, version) => {
162
162
  patchCollection(mongodb, version);
163
163
  patchDatabase(mongodb, version);
164
164
  });
@@ -39,9 +39,7 @@ describe('protect input-tracing mongodb', function() {
39
39
  ({ core, simulateRequestScope } = initProtectFixture());
40
40
  require('../../get-source-context')(core);
41
41
 
42
- core.depHooks.resolve
43
- .withArgs({ name: 'mongodb' })
44
- .yields({ Collection, Db });
42
+ core.depHooks.resolve.yields({ Collection, Db });
45
43
 
46
44
  instr = require('./mongodb')(core);
47
45
  instr.install();
@@ -247,7 +245,7 @@ describe('protect input-tracing mongodb', function() {
247
245
  command() { }
248
246
  }
249
247
  core.depHooks.resolve
250
- .withArgs({ name: 'mongodb' })
248
+ .withArgs(sinon.match({ name: 'mongodb' }))
251
249
  .yields({ Collection, Db }, 'v5.x.x');
252
250
 
253
251
  const instr = require('./mongodb')(core);