@contrast/protect 1.49.0 → 1.51.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 (56) 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/init-domain.js +4 -39
  4. package/lib/error-handlers/init-domain.test.js +3 -15
  5. package/lib/error-handlers/install/express.js +162 -0
  6. package/lib/error-handlers/install/express.test.js +290 -0
  7. package/lib/error-handlers/install/hapi.js +2 -2
  8. package/lib/error-handlers/install/hapi.test.js +2 -2
  9. package/lib/error-handlers/install/koa2.js +1 -1
  10. package/lib/error-handlers/install/restify.js +1 -1
  11. package/lib/error-handlers/install/restify.test.js +1 -1
  12. package/lib/hardening/install/node-serialize0.js +2 -2
  13. package/lib/hardening/install/node-serialize0.test.js +1 -4
  14. package/lib/index.d.ts +3 -3
  15. package/lib/input-analysis/index.js +1 -1
  16. package/lib/input-analysis/index.test.js +1 -1
  17. package/lib/input-analysis/install/body-parser1.js +2 -2
  18. package/lib/input-analysis/install/busboy1.js +1 -1
  19. package/lib/input-analysis/install/cookie-parser1.js +1 -1
  20. package/lib/input-analysis/install/{express4.js → express.js} +61 -20
  21. package/lib/input-analysis/install/{express4.test.js → express.test.js} +92 -59
  22. package/lib/input-analysis/install/formidable1.js +1 -1
  23. package/lib/input-analysis/install/hapi.js +1 -1
  24. package/lib/input-analysis/install/hapi.test.js +6 -14
  25. package/lib/input-analysis/install/http.js +2 -9
  26. package/lib/input-analysis/install/koa-body5.js +1 -1
  27. package/lib/input-analysis/install/koa-bodyparser4.js +1 -1
  28. package/lib/input-analysis/install/koa2.js +5 -5
  29. package/lib/input-analysis/install/multer1.js +1 -1
  30. package/lib/input-analysis/install/qs6.js +1 -1
  31. package/lib/input-analysis/install/restify.js +1 -1
  32. package/lib/input-analysis/install/restify.test.js +1 -1
  33. package/lib/input-analysis/install/universal-cookie4.js +1 -1
  34. package/lib/input-tracing/install/child-process.js +1 -1
  35. package/lib/input-tracing/install/fs.js +2 -2
  36. package/lib/input-tracing/install/fs.test.js +2 -2
  37. package/lib/input-tracing/install/http.js +2 -2
  38. package/lib/input-tracing/install/http2.js +2 -2
  39. package/lib/input-tracing/install/marsdb.js +2 -2
  40. package/lib/input-tracing/install/marsdb.test.js +1 -1
  41. package/lib/input-tracing/install/mongodb.js +2 -2
  42. package/lib/input-tracing/install/mongodb.test.js +2 -4
  43. package/lib/input-tracing/install/mssql.js +3 -3
  44. package/lib/input-tracing/install/mssql.test.js +2 -2
  45. package/lib/input-tracing/install/mysql.js +7 -9
  46. package/lib/input-tracing/install/postgres.js +3 -3
  47. package/lib/input-tracing/install/postgres.test.js +2 -10
  48. package/lib/input-tracing/install/sequelize.js +2 -2
  49. package/lib/input-tracing/install/spdy.js +2 -2
  50. package/lib/input-tracing/install/sqlite3.js +2 -2
  51. package/lib/input-tracing/install/vm.js +2 -2
  52. package/lib/semantic-analysis/install/libxmljs.js +3 -3
  53. package/lib/semantic-analysis/install/libxmljs.test.js +2 -2
  54. package/package.json +12 -14
  55. package/lib/error-handlers/install/express4.js +0 -138
  56. package/lib/error-handlers/install/express4.test.js +0 -238
@@ -25,7 +25,7 @@ module.exports = function(core) {
25
25
  require('./init-domain')(core);
26
26
 
27
27
  // installers
28
- require('./install/express4')(core);
28
+ require('./install/express')(core);
29
29
  require('./install/fastify')(core);
30
30
  require('./install/hapi')(core);
31
31
  require('./install/koa2')(core);
@@ -8,7 +8,7 @@ describe('protect error-handlers', function () {
8
8
  let core, errorHandlers;
9
9
 
10
10
  const installerList = [
11
- 'express4ErrorHandler',
11
+ 'expressErrorHandler',
12
12
  'fastifyErrorHandler',
13
13
  'hapiErrorHandler',
14
14
  'koa2ErrorHandler',
@@ -15,47 +15,12 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const process = require('process');
19
- const semver = require('semver');
18
+ const { Domain } = require('async-hook-domain');
20
19
 
21
20
  module.exports = function(core) {
22
- const {
23
- logger,
24
- protect: { errorHandlers }
25
- } = core;
21
+ const { protect: { errorHandlers } } = core;
26
22
 
27
- Object.assign(errorHandlers, initSupportedDomainPackage());
28
-
29
- return errorHandlers.initDomain = function(req, res) {
30
- const { AsyncHookDomain, Domain } = errorHandlers;
31
-
32
- if (AsyncHookDomain) {
33
- new AsyncHookDomain(errorHandlers.commonHandler);
34
- } else {
35
- const domain = new Domain();
36
- domain.add(req);
37
- domain.add(res);
38
- domain.on('error', errorHandlers.commonHandler);
39
- return domain;
40
- }
23
+ return errorHandlers.initDomain = function initDomain() {
24
+ return new Domain(errorHandlers.commonHandler);
41
25
  };
42
-
43
- function initSupportedDomainPackage() {
44
- let AsyncHookDomain, Domain;
45
-
46
- if (semver.lt(process.version, '16.0.0')) {
47
- logger.info(
48
- '%s. %s. %s.',
49
- 'falling back to deprecated \'domain\' module for async SecurityException handling',
50
- 'upgrade to Node 16 LTS or above to allow use of \'async-hook-domain\' modern alternative',
51
- 'upgrading will resolve any deprecation warnings and prevent the logging of this message'
52
- );
53
-
54
- Domain = require('domain').Domain;
55
- } else {
56
- AsyncHookDomain = require('async-hook-domain');
57
- }
58
-
59
- return { AsyncHookDomain, Domain };
60
- }
61
26
  };
@@ -5,30 +5,18 @@ const sinon = require('sinon');
5
5
  const { initProtectFixture } = require('@contrast/test/fixtures');
6
6
 
7
7
  describe('protect error-handlers init-domain', function () {
8
- let core, errorHandlers, initDomain;
8
+ let core;
9
9
 
10
10
  beforeEach(function () {
11
11
  ({ core } = initProtectFixture());
12
12
 
13
13
  sinon.stub(core.protect.errorHandlers, 'commonHandler');
14
-
15
- errorHandlers = core.protect.errorHandlers;
16
- initDomain = errorHandlers.initDomain;
17
14
  });
18
15
 
19
16
  describe('domain integration', function () {
20
- beforeEach(function () {
21
- sinon.stub(errorHandlers, 'AsyncHookDomain');
22
- });
23
-
24
- it('initializes correct domain', function () {
25
- expect(core.protect.errorHandlers.AsyncHookDomain).to.be.a('function');
26
- expect(core.protect.errorHandlers.Domain).to.be.undefined;
27
- });
28
-
29
17
  it('instantiates async-hook-domain with common error handler', function () {
30
- initDomain();
31
- expect(errorHandlers.AsyncHookDomain).to.have.been.calledWith(errorHandlers.commonHandler);
18
+ const d = core.protect.errorHandlers.initDomain();
19
+ expect(d.onerror).to.equal(core.protect.errorHandlers.commonHandler);
32
20
  });
33
21
  });
34
22
  });
@@ -0,0 +1,162 @@
1
+ /*
2
+ * Copyright: 2024 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const SecurityException = require('../../security-exception');
19
+ const { patchType } = require('../constants');
20
+
21
+ module.exports = function (core) {
22
+ const {
23
+ logger,
24
+ depHooks,
25
+ patcher,
26
+ protect,
27
+ } = core;
28
+
29
+ const expressErrorHandler = protect.errorHandlers.expressErrorHandler = {};
30
+
31
+ function checkSecurityException(err, funcKey, orig, throwErr = false) {
32
+ const sourceContext = protect.getSourceContext();
33
+ const isSecurityException = SecurityException.isSecurityException(err);
34
+
35
+ if (isSecurityException && sourceContext) {
36
+ const blockInfo = sourceContext.securityException;
37
+
38
+ sourceContext.block(...blockInfo);
39
+ return;
40
+ }
41
+
42
+ if (!sourceContext && isSecurityException) {
43
+ logger.info({ funcKey }, 'source context not found; unable to handle response');
44
+ return;
45
+ }
46
+
47
+ if (throwErr) {
48
+ throw err;
49
+ } else {
50
+ return orig();
51
+ }
52
+ }
53
+
54
+ expressErrorHandler.install = function () {
55
+
56
+ // Express 4 and 5
57
+ depHooks.resolve({ name: 'finalhandler', version: '<3' }, (finalhandler) =>
58
+ patcher.patch(finalhandler, {
59
+ name: 'finalHandler',
60
+ patchType,
61
+ post(data) {
62
+ data.result = patcher.patch(data.result, {
63
+ name: 'finalHandler.returnedFunction',
64
+ patchType,
65
+ around(orig, data) {
66
+ const [err] = data.args;
67
+ checkSecurityException(err, data.funcKey, orig);
68
+ }
69
+ });
70
+ },
71
+ })
72
+ );
73
+
74
+ function postHook() {
75
+ return function(data) {
76
+ patcher.patch(data.result, 'handle', {
77
+ name: 'handle',
78
+ patchType,
79
+ post(data) {
80
+ data.result = data.result?.catch?.((err) => {
81
+ checkSecurityException(err, data.funcKey, data.orig, true);
82
+ });
83
+ }
84
+ });
85
+ };
86
+ }
87
+
88
+ // Express 4
89
+ depHooks.resolve({ name: 'express', version: '4', file: 'lib/router/layer.js' }, (Layer) => {
90
+
91
+ patcher.patch(Layer.prototype, 'handle_error', {
92
+ name: 'Layer.prototype.handle_error',
93
+ patchType,
94
+ around(orig, data) {
95
+ const [err] = data.args;
96
+ checkSecurityException(err, data.funcKey, orig);
97
+ }
98
+ });
99
+
100
+ return patcher.patch(Layer, {
101
+ name: 'Layer',
102
+ patchType,
103
+ post: postHook()
104
+ });
105
+
106
+ });
107
+
108
+ // Express 5
109
+ depHooks.resolve({ name: 'router', version: '2', file: 'lib/layer.js' }, (Layer) => {
110
+
111
+ patcher.patch(Layer.prototype, 'handleError', {
112
+ name: 'Layer.prototype.handleError',
113
+ patchType,
114
+ around(orig, data) {
115
+ const [err] = data.args;
116
+ checkSecurityException(err, data.funcKey, orig);
117
+ }
118
+ });
119
+
120
+ return patcher.patch(Layer, {
121
+ name: 'router.Layer',
122
+ patchType,
123
+ post: postHook()
124
+ });
125
+ });
126
+
127
+ function preHook() {
128
+ return function(data) {
129
+ if (typeof data.args[1] === 'function') {
130
+ patcher.patch(data.args, '1', {
131
+ name: 'express.route-handler',
132
+ patchType,
133
+ post(data) {
134
+ data.result = data.result?.catch?.((err) => {
135
+ checkSecurityException(err, data.funcKey, data.orig, true);
136
+ });
137
+ }
138
+ });
139
+ }
140
+ };
141
+ }
142
+
143
+ // Express 4
144
+ depHooks.resolve({ name: 'express', version: '4', file: 'lib/router/index.js' }, (Router) => {
145
+ patcher.patch(Router.prototype.constructor, 'param', {
146
+ name: 'Router.prototype.constructor.param',
147
+ patchType,
148
+ pre: preHook()
149
+ });
150
+ });
151
+
152
+ // Express 5
153
+ depHooks.resolve({ name: 'router', version: '2' }, (Router) => {
154
+ patcher.patch(Router.prototype, 'param', {
155
+ name: 'Router.prototype.param',
156
+ patchType,
157
+ pre: preHook()
158
+ });
159
+ });
160
+ };
161
+ return expressErrorHandler;
162
+ };
@@ -0,0 +1,290 @@
1
+ /* eslint-disable */
2
+ 'use strict';
3
+
4
+ const sinon = require('sinon');
5
+ const { expect } = require('chai');
6
+ const scopes = require('@contrast/scopes');
7
+ const patcher = require('@contrast/patcher');
8
+ const mocks = require('@contrast/test/mocks');
9
+ const SecurityException = require('../../security-exception');
10
+
11
+ describe('protect error-handlers express', function () {
12
+ let core, store, errorHandlerInstr;
13
+
14
+ const throwingHandler = (error) => async function () {
15
+ await Promise.reject(error);
16
+ };
17
+
18
+ beforeEach(function () {
19
+ core = mocks.core();
20
+ core.config = mocks.config();
21
+ core.logger = mocks.logger();
22
+ core.scopes = scopes(core);
23
+ core.protect = mocks.protect();
24
+ require('../../get-source-context')(core);
25
+ core.depHooks = mocks.depHooks();
26
+ core.patcher = patcher(core);
27
+
28
+ store = {
29
+ protect: {
30
+ block: sinon.stub(),
31
+ securityException: ['block', 'cmd-injection']
32
+ }
33
+ };
34
+
35
+ sinon.spy(core.patcher, 'patch');
36
+ });
37
+
38
+ describe('finalhandler', function () {
39
+ let finalhandler, returnedFn;
40
+
41
+ beforeEach(function () {
42
+ finalhandler = function () {
43
+ return function () { };
44
+ };
45
+
46
+ core.depHooks.resolve.withArgs({ name: 'finalhandler', version: '<3' }).yields(finalhandler);
47
+
48
+ errorHandlerInstr = require('./express')(core);
49
+ errorHandlerInstr.install();
50
+
51
+ const patchedFinalhandler = core.patcher.patch.getCall(0).returnValue;
52
+ returnedFn = patchedFinalhandler();
53
+ });
54
+
55
+ it('should block the request when there is SecurityException', function () {
56
+ const error = SecurityException.create();
57
+
58
+ core.scopes.sources.run(store, () => {
59
+ returnedFn(error);
60
+ expect(core.logger.info).not.to.have.been.called;
61
+ expect(store.protect.block).to.have.been.calledWith('block', 'cmd-injection');
62
+ });
63
+ });
64
+
65
+ it('should not block the request when there is SecurityException but sourceContext is missing', function () {
66
+ const error = SecurityException.create();
67
+
68
+ core.scopes.sources.run({}, () => {
69
+ returnedFn(error);
70
+ expect(core.logger.info).to.have.been.calledWith(
71
+ { funcKey: 'protect-error-handling:finalHandler.returnedFunction' },
72
+ 'source context not found; unable to handle response',
73
+ );
74
+ });
75
+ });
76
+
77
+ it('should skip the instrumentation when there is no SecurityException', function () {
78
+ const error = new Error('Error');
79
+
80
+ core.scopes.sources.run({}, () => {
81
+ returnedFn(error);
82
+ expect(core.logger.info).not.to.have.been.called;
83
+ expect(store.protect.block).not.to.have.been.called;
84
+ });
85
+ });
86
+ });
87
+
88
+ [
89
+ { name: 'express', version: '4', file: 'lib/router/layer.js' },
90
+ { name: 'router', version: '2', file: 'lib/layer.js' }
91
+ ].forEach((args) => {
92
+ const fn = args.name === 'express' ? 'handle_error' : 'handleError';
93
+ describe(`${args.name} Layer.prototype.${fn}`, function () {
94
+ let Layer;
95
+
96
+ beforeEach(function () {
97
+ Layer = function () { };
98
+
99
+ Layer.prototype[fn] = function () { };
100
+
101
+ core.depHooks.resolve.withArgs(args).yields(Layer);
102
+
103
+ errorHandlerInstr = require('./express')(core);
104
+ errorHandlerInstr.install();
105
+ });
106
+
107
+ it('should block the request when there is SecurityException', function () {
108
+ const error = SecurityException.create();
109
+
110
+ core.scopes.sources.run(store, () => {
111
+ Layer.prototype[fn](error);
112
+ expect(core.logger.info).not.to.have.been.called;
113
+ expect(store.protect.block).to.have.been.calledWith('block', 'cmd-injection');
114
+ });
115
+ });
116
+
117
+ it('should not block the request when there is SecurityException but sourceContext is missing', function () {
118
+ const error = SecurityException.create();
119
+
120
+ core.scopes.sources.run({}, () => {
121
+ Layer.prototype[fn](error);
122
+ expect(core.logger.info).to.have.been.calledWith(
123
+ { funcKey: `protect-error-handling:Layer.prototype.${fn}` },
124
+ 'source context not found; unable to handle response'
125
+ );
126
+ });
127
+ });
128
+
129
+ it('should skip the instrumentation when there is no SecurityException', function () {
130
+ const error = new Error('Error');
131
+
132
+ core.scopes.sources.run({}, () => {
133
+ Layer.prototype[fn](error);
134
+ expect(core.logger.info).not.to.have.been.called;
135
+ expect(store.protect.block).not.to.have.been.called;
136
+ });
137
+ });
138
+ });
139
+
140
+ describe(`${args.name} Layer handle`, function () {
141
+ let Layer, patchedLayer;
142
+ const error = SecurityException.create();
143
+ const fn = throwingHandler(error);
144
+ beforeEach(function () {
145
+ Layer = function () {
146
+ return {
147
+ handle: fn
148
+ }
149
+ };
150
+
151
+ errorHandlerInstr = require('./express')(core);
152
+ errorHandlerInstr.install();
153
+ [patchedLayer] = core.depHooks.resolve.withArgs(args).yield(Layer);
154
+ });
155
+
156
+ it('should block the request when there is SecurityException', async function () {
157
+ await core.scopes.sources.run(store, async () => {
158
+ await patchedLayer().handle();
159
+ });
160
+ expect(core.logger.info).not.to.have.been.called;
161
+ expect(store.protect.block).to.have.been.calledWith('block', 'cmd-injection');
162
+ });
163
+
164
+ it('should not block the request when there is SecurityException but sourceContext is missing', async function () {
165
+ await core.scopes.sources.run({}, async () => {
166
+ await patchedLayer().handle();
167
+ });
168
+
169
+ expect(core.logger.info).to.have.been.calledWith(
170
+ { funcKey: 'protect-error-handling:handle' },
171
+ 'source context not found; unable to handle response',
172
+ );
173
+ });
174
+
175
+ it('should skip the instrumentation when there is no SecurityException', async function () {
176
+ const error = new Error('Error');
177
+ const fn = throwingHandler(error);
178
+ Layer = function () {
179
+ return {
180
+ handle: fn
181
+ }
182
+ };
183
+
184
+ errorHandlerInstr = require('./express')(core);
185
+ errorHandlerInstr.install();
186
+ [patchedLayer] = core.depHooks.resolve.withArgs(args).yield(Layer);
187
+
188
+ try {
189
+ await core.scopes.sources.run(store, async () => {
190
+ await patchedLayer().handle();
191
+ });
192
+ } catch (err) {
193
+ expect(err).to.equal(error);
194
+ expect(core.logger.info).not.to.have.been.called;
195
+ expect(store.protect.block).not.to.have.been.called;
196
+ }
197
+ });
198
+ });
199
+ });
200
+
201
+ [
202
+ { name: 'express', version: '4', file: 'lib/router/index.js' },
203
+ { name: 'router', version: '2' }
204
+ ].forEach((args) => {
205
+ describe(`${args.name} Router param`, function () {
206
+ let Router, param;
207
+ const sampleFn = function () { };
208
+
209
+ beforeEach(function () {
210
+
211
+ Router = function() { };
212
+ if (args.name === 'express') {
213
+ Router.prototype.constructor = {
214
+ param: function () { },
215
+ };
216
+ param = (...args) => Router.prototype.constructor.param(...args);
217
+ } else {
218
+ Router.prototype = {
219
+ param: function () { },
220
+ };
221
+ param = (...args) => Router.prototype.param(...args);
222
+ }
223
+ core.depHooks.resolve.withArgs(args).yields(Router);
224
+
225
+ core.patcher.patch.resetHistory();
226
+
227
+ errorHandlerInstr = require('./express')(core);
228
+ errorHandlerInstr.install();
229
+ });
230
+
231
+ it('should patch the function for the param property', function () {
232
+ param('sampleFn', sampleFn);
233
+ expect(core.patcher.patch).to.have.been.calledWith(sinon.match.array, '1', sinon.match.object);
234
+ });
235
+
236
+ it('should block the request when there is SecurityException', async function () {
237
+ const error = SecurityException.create();
238
+ const fn = throwingHandler(error);
239
+
240
+ param('fn', fn);
241
+
242
+ const patchedFn = core.patcher.patch.getCall(1).returnValue[1];
243
+
244
+ await core.scopes.sources.run(store, async () => {
245
+ await patchedFn();
246
+ });
247
+
248
+ expect(core.logger.info).not.to.have.been.called;
249
+ expect(store.protect.block).to.have.been.calledWith('block', 'cmd-injection');
250
+ });
251
+
252
+ it('should not block the request when there is SecurityException but sourceContext is missing', async function () {
253
+ const error = SecurityException.create();
254
+ const fn = throwingHandler(error);
255
+
256
+ param('fn', fn);
257
+
258
+ const patchedFn = core.patcher.patch.getCall(1).returnValue[1];
259
+
260
+ await core.scopes.sources.run({}, async () => {
261
+ await patchedFn();
262
+ });
263
+
264
+ expect(core.logger.info).to.have.been.calledWith(
265
+ { funcKey: 'protect-error-handling:express.route-handler' },
266
+ 'source context not found; unable to handle response',
267
+ );
268
+ });
269
+
270
+ it('should skip the instrumentation when there is no SecurityException', async function () {
271
+ const error = new Error('Error');
272
+ const fn = throwingHandler(error);
273
+
274
+ param('fn', fn);
275
+
276
+ const patchedFn = core.patcher.patch.getCall(1).returnValue[1];
277
+
278
+ try {
279
+ await core.scopes.sources.run(store, async () => {
280
+ await patchedFn();
281
+ });
282
+ } catch (err) {
283
+ expect(err).to.equal(error);
284
+ expect(core.logger.info).not.to.have.been.called;
285
+ expect(store.protect.block).not.to.have.been.called;
286
+ }
287
+ });
288
+ });
289
+ });
290
+ });
@@ -60,12 +60,12 @@ module.exports = function (core) {
60
60
 
61
61
  hapiErrorHandler.install = function () {
62
62
  depHooks.resolve(
63
- { name: 'boom' },
63
+ { name: 'boom', version: '<8' },
64
64
  (boom) => registerErrorHandler(boom, 'boom'),
65
65
  );
66
66
 
67
67
  depHooks.resolve(
68
- { name: '@hapi/boom' },
68
+ { name: '@hapi/boom', version: '<11' },
69
69
  (boom) => registerErrorHandler(boom, '@hapi/boom'),
70
70
  );
71
71
  };
@@ -39,8 +39,8 @@ describe('protect error-handlers hapi', function () {
39
39
  Boom.boomify = function boom() { };
40
40
  HapiBoom.boomify = function hapiBoom() { };
41
41
 
42
- core.depHooks.resolve.withArgs({ name: Boom.name }).yields(Boom);
43
- core.depHooks.resolve.withArgs({ name: HapiBoom.name }).yields(HapiBoom);
42
+ core.depHooks.resolve.withArgs(sinon.match({ name: Boom.name })).yields(Boom);
43
+ core.depHooks.resolve.withArgs(sinon.match({ name: HapiBoom.name })).yields(HapiBoom);
44
44
 
45
45
  errorHandler = require('./hapi')(core);
46
46
  errorHandler.install();
@@ -30,7 +30,7 @@ module.exports = function (core) {
30
30
  const koa2ErrorHandler = protect.errorHandlers.koa2ErrorHandler = {};
31
31
 
32
32
  koa2ErrorHandler.install = function () {
33
- depHooks.resolve({ name: 'koa', version: '>=2.3.0' }, (Koa) => {
33
+ depHooks.resolve({ name: 'koa', version: '>=2.3.0 <3' }, (Koa) => {
34
34
  patcher.patch(Koa.prototype, 'handleRequest', {
35
35
  name: 'Koa.Application.handleRequest',
36
36
  patchType,
@@ -24,7 +24,7 @@ module.exports = function init(core) {
24
24
  return protect.errorHandlers.restifyErrorHandler = {
25
25
  install() {
26
26
  depHooks.resolve(
27
- { name: 'restify', file: 'lib/server.js', version: '>=8' },
27
+ { name: 'restify', file: 'lib/server.js', version: '>=8 <12' },
28
28
  (Server) => {
29
29
  patcher.patch(Server.prototype, '_onHandlerError', {
30
30
  name: 'restify.Server.prototype._onHandlerError',
@@ -15,7 +15,7 @@ describe('protect error-handlers restify v8+', function () {
15
15
  store = { protect: { block: sinon.stub(), securityException: ['block'] } };
16
16
 
17
17
  core.depHooks.resolve
18
- .withArgs({ name: 'restify', file: 'lib/server.js', version: '>=8' })
18
+ .withArgs({ name: 'restify', file: 'lib/server.js', version: '>=8 <12' })
19
19
  .yields(Server);
20
20
 
21
21
  core.protect.errorHandlers.restifyErrorHandler.install();
@@ -32,13 +32,13 @@ module.exports = function(core) {
32
32
  const method = 'unserialize';
33
33
 
34
34
  depHooks.resolve(
35
- { name, version: '<1.0.0' },
35
+ { name, version: '<1' },
36
36
  (nodeSerialize) => {
37
37
  patcher.patch(nodeSerialize, method, {
38
38
  name,
39
39
  patchType,
40
40
  pre({ args: [value], hooked, orig }) {
41
- const sourceContext = protect.getSourceContext(`${name}.${method}`);
41
+ const sourceContext = protect.getSourceContext();
42
42
 
43
43
  if (!sourceContext || !value) return;
44
44
 
@@ -18,10 +18,7 @@ describe('protect hardening node-serialize0', function () {
18
18
  core = mocks.core();
19
19
  core.logger = mocks.logger();
20
20
  core.depHooks = mocks.depHooks();
21
- core.depHooks
22
- .resolve
23
- .withArgs({ name: 'node-serialize', version: '<1.0.0' })
24
- .yields(mockLib);
21
+ core.depHooks.resolve.yields(mockLib);
25
22
  core.patcher = patcher(core);
26
23
  core.scopes = scopes(core);
27
24
  core.protect = mocks.protect();
package/lib/index.d.ts CHANGED
@@ -17,7 +17,7 @@ import { ReqData, ProtectMessage, ResultMap, ProtectRuleMode } from '@contrast/c
17
17
  import { IncomingMessage, ServerResponse } from 'node:http';
18
18
  import * as http from 'node:http';
19
19
  import * as https from 'node:https';
20
- import { Domain } from 'domain';
20
+ import { Domain } from 'async-hook-domain';
21
21
 
22
22
  type Http = typeof http;
23
23
  type Https = typeof https;
@@ -114,7 +114,7 @@ export interface Protect {
114
114
  }
115
115
  errorHandlers: {
116
116
  commonHandler: (err: Error) => void;
117
- initDomain: () => void | Domain;
117
+ initDomain: () => Domain;
118
118
  fastify3ErrorHandler: {
119
119
  _userHandler: null | ((...args: any[]) => any),
120
120
  defaultErrorHandler: (error: Error, request: IncomingMessage, reply: ServerResponse) => void,
@@ -122,7 +122,7 @@ export interface Protect {
122
122
  install: () => void
123
123
  }
124
124
  koa2ErrorHandler: { install: () => void },
125
- express4ErrorHandler: { install: () => void },
125
+ expressErrorHandler: { install: () => void },
126
126
  install: () => void,
127
127
  },
128
128
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -39,7 +39,7 @@ module.exports = function(core) {
39
39
  // framework specific instrumentation
40
40
  require('./install/fastify')(core);
41
41
  require('./install/koa2')(core);
42
- require('./install/express4')(core);
42
+ require('./install/express')(core);
43
43
  require('./install/hapi')(core);
44
44
  require('./install/restify')(core);
45
45