@contrast/protect 1.2.1 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/lib/error-handlers/constants.js +15 -0
  2. package/lib/error-handlers/index.js +17 -0
  3. package/lib/error-handlers/install/express4.js +89 -0
  4. package/lib/error-handlers/install/fastify3.js +17 -4
  5. package/lib/error-handlers/install/koa2.js +16 -2
  6. package/lib/esm-loader.mjs +15 -0
  7. package/lib/get-source-context.js +33 -0
  8. package/lib/hardening/constants.js +20 -0
  9. package/lib/hardening/handlers.js +65 -0
  10. package/lib/hardening/index.js +29 -0
  11. package/lib/hardening/install/node-serialize0.js +59 -0
  12. package/lib/index.d.ts +127 -19
  13. package/lib/index.js +19 -0
  14. package/lib/input-analysis/constants.js +20 -0
  15. package/lib/input-analysis/handlers.js +201 -16
  16. package/lib/input-analysis/index.js +40 -3
  17. package/lib/input-analysis/install/body-parser1.js +122 -0
  18. package/lib/input-analysis/install/cookie-parser1.js +80 -0
  19. package/lib/input-analysis/install/express4.js +103 -0
  20. package/lib/input-analysis/install/fastify3.js +51 -24
  21. package/lib/input-analysis/install/formidable1.js +72 -0
  22. package/lib/input-analysis/install/http.js +30 -4
  23. package/lib/input-analysis/install/koa-body5.js +63 -0
  24. package/lib/input-analysis/install/koa-bodyparser4.js +64 -0
  25. package/lib/input-analysis/install/koa2.js +38 -48
  26. package/lib/input-analysis/install/multer1.js +88 -0
  27. package/lib/input-analysis/install/qs6.js +57 -0
  28. package/lib/input-analysis/install/universal-cookie4.js +52 -0
  29. package/lib/input-analysis/ip-analysis.js +76 -0
  30. package/lib/input-analysis/virtual-patches.js +109 -0
  31. package/lib/input-tracing/constants.js +15 -0
  32. package/lib/input-tracing/handlers/index.js +225 -66
  33. package/lib/input-tracing/index.js +25 -2
  34. package/lib/input-tracing/install/child-process.js +28 -7
  35. package/lib/input-tracing/install/eval.js +60 -0
  36. package/lib/input-tracing/install/fs.js +21 -4
  37. package/lib/input-tracing/install/http.js +63 -0
  38. package/lib/input-tracing/install/mongodb.js +233 -0
  39. package/lib/input-tracing/install/mysql.js +21 -4
  40. package/lib/input-tracing/install/postgres.js +20 -4
  41. package/lib/input-tracing/install/sequelize.js +22 -5
  42. package/lib/input-tracing/install/sqlite3.js +21 -4
  43. package/lib/input-tracing/install/vm.js +132 -0
  44. package/lib/make-response-blocker.js +15 -0
  45. package/lib/make-source-context.js +22 -1
  46. package/lib/security-exception.js +15 -0
  47. package/lib/semantic-analysis/handlers.js +160 -0
  48. package/lib/semantic-analysis/index.js +38 -0
  49. package/lib/throw-security-exception.js +17 -6
  50. package/package.json +10 -12
  51. package/lib/cli-rewriter.js +0 -20
  52. package/lib/input-analysis/install/co-body.js +0 -51
  53. package/lib/input-analysis/install/cookie-parser.js +0 -48
  54. package/lib/input-analysis/install/formidable.js +0 -53
  55. package/lib/input-analysis/install/multer.js +0 -52
  56. package/lib/input-analysis/install/qs.js +0 -40
  57. package/lib/input-analysis/install/universal-cookie.js +0 -34
  58. package/lib/input-tracing/handlers/nosql-injection-mongo.js +0 -48
  59. package/lib/utils.js +0 -88
@@ -0,0 +1,103 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const { patchType } = require('../constants');
19
+ const { isSecurityException } = require('../../security-exception');
20
+
21
+ /**
22
+ * Function that exports an install method to patch Express framework with our instrumentation
23
+ * @param {Object} core - the core Contrast object in v5
24
+ * @return {Object} object with install method and the other relative functions exported for testing purposes
25
+ */
26
+ module.exports = (core) => {
27
+ const {
28
+ depHooks,
29
+ patcher,
30
+ logger,
31
+ protect,
32
+ protect: { inputAnalysis },
33
+ } = core;
34
+
35
+ /**
36
+ * registers a depHook for express module instrumentation
37
+ */
38
+ function install() {
39
+ depHooks.resolve({ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/middleware/query.js' }, (query) => patcher.patch(query, {
40
+ name: 'Express.query',
41
+ patchType,
42
+ post(data) {
43
+ data.result = patcher.patch(data.result, {
44
+ name: 'Express.query',
45
+ patchType,
46
+ pre(data) {
47
+ const [req, , origNext] = data.args;
48
+
49
+ function contrastNext(origErr) {
50
+ const sourceContext = protect.getSourceContext('Express.query');
51
+ let securityException;
52
+
53
+ // It is possible for the query to be already parsed by `qs`
54
+ // which means that we've already handled/analyzed it.
55
+ // So we check whether we already have the `parsedQuery` property in the context
56
+ if (sourceContext && req.query && Object.keys(req.query).length && (!('parsedQuery' in sourceContext))) {
57
+ sourceContext.parsedQuery = req.query;
58
+
59
+ try {
60
+ inputAnalysis.handleQueryParams(sourceContext, req.query);
61
+ } catch (err) {
62
+ if (isSecurityException(err)) {
63
+ securityException = err;
64
+ } else {
65
+ logger.error({ err }, 'Unexpected error during input analysis');
66
+ }
67
+ }
68
+ }
69
+
70
+ const error = securityException || origErr;
71
+
72
+ origNext(error);
73
+ }
74
+
75
+ data.args[2] = contrastNext;
76
+ }
77
+ });
78
+ }
79
+ }));
80
+
81
+ depHooks.resolve({ name: 'express', version: '>=4.0.0 <5.0.0', file: 'lib/router/layer.js' }, (Layer) => {
82
+ patcher.patch(Layer.prototype, 'handle_request', {
83
+ name: 'express.Layer.prototype.handle_request',
84
+ patchType,
85
+ pre(data) {
86
+ const { obj: { params } } = data;
87
+ const sourceContext = protect.getSourceContext('Express.Layer.handle_request');
88
+
89
+ if (sourceContext && params && Object.keys(params).length) {
90
+ sourceContext.parsedParams = params;
91
+ inputAnalysis.handleUrlParams(sourceContext, params);
92
+ }
93
+ }
94
+ });
95
+ });
96
+ }
97
+
98
+ const express4Instrumentation = inputAnalysis.express4Instrumentation = {
99
+ install
100
+ };
101
+
102
+ return express4Instrumentation;
103
+ };
@@ -1,5 +1,23 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
1
16
  'use strict';
2
17
 
18
+ const { patchType } = require('../constants');
19
+ const { isSecurityException } = require('../../security-exception');
20
+
3
21
  /**
4
22
  * Function that exports an install method to patch Fastify framework with our instrumentation
5
23
  * @param {Object} core - the core Contrast object in v5
@@ -10,7 +28,7 @@ module.exports = (core) => {
10
28
  depHooks,
11
29
  patcher,
12
30
  logger,
13
- scopes: { sources },
31
+ protect,
14
32
  protect: { inputAnalysis },
15
33
  } = core;
16
34
 
@@ -29,7 +47,7 @@ module.exports = (core) => {
29
47
  function patchFastify(fastify) {
30
48
  return patcher.patch(fastify, {
31
49
  name: 'fastify.build',
32
- patchType: 'framework-patch',
50
+ patchType,
33
51
  post({ result: server }) {
34
52
  server.addHook('preValidation', preValidationHook);
35
53
  },
@@ -44,36 +62,45 @@ module.exports = (core) => {
44
62
  * @param {Function} done callback to signal the hook is finished.
45
63
  */
46
64
  function preValidationHook(request, reply, done) {
47
- const sourceContext = sources.getStore()?.protect;
65
+ const sourceContext = protect.getSourceContext('Fastify.preValidationHook');
48
66
 
49
- if (!sourceContext) {
50
- logger.debug('source context not available in fastify prevalidation hook');
51
- } else {
52
- if (request.params) {
53
- sourceContext.parsedParams = request.params;
54
- inputAnalysis.handleUrlParams(sourceContext, request.params);
55
- }
56
- if (request.cookies) {
57
- sourceContext.parsedCookies = request.cookies;
58
- inputAnalysis.handleCookies(sourceContext, request.cookies);
59
- }
60
- if (request.body) {
61
- sourceContext.parsedBody = request.body;
62
- inputAnalysis.handleParsedBody(sourceContext, request.body);
63
- }
67
+ let securityException;
64
68
 
65
- if (request.query) {
66
- sourceContext.parsedQuery = request.query;
67
- inputAnalysis.handleQueryParams(sourceContext, request.query);
69
+ if (sourceContext) {
70
+ try {
71
+ if (request.params) {
72
+ sourceContext.parsedParams = request.params;
73
+ inputAnalysis.handleUrlParams(sourceContext, request.params);
74
+ }
75
+ if (request.cookies) {
76
+ sourceContext.parsedCookies = request.cookies;
77
+ inputAnalysis.handleCookies(sourceContext, request.cookies);
78
+ }
79
+ if (request.body) {
80
+ sourceContext.parsedBody = request.body;
81
+ inputAnalysis.handleParsedBody(sourceContext, request.body);
82
+ }
83
+
84
+ if (request.query) {
85
+ sourceContext.parsedQuery = request.query;
86
+ inputAnalysis.handleQueryParams(sourceContext, request.query);
87
+ }
88
+ } catch (err) {
89
+ if (isSecurityException(err)) {
90
+ securityException = err;
91
+ } else {
92
+ logger.error({ err }, 'Unexpected error during input analysis');
93
+ }
68
94
  }
69
95
  }
70
- done();
96
+
97
+ done(securityException);
71
98
  }
72
99
 
73
- const fastifyInstrumentation = inputAnalysis.fastifyInstrumentation = {
100
+ const fastify3Instrumentation = inputAnalysis.fastify3Instrumentation = {
74
101
  preValidationHook,
75
102
  install,
76
103
  };
77
104
 
78
- return fastifyInstrumentation;
105
+ return fastify3Instrumentation;
79
106
  };
@@ -0,0 +1,72 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const { patchType } = require('../constants');
19
+
20
+ module.exports = (core) => {
21
+ const {
22
+ depHooks,
23
+ patcher,
24
+ logger,
25
+ protect,
26
+ protect: { inputAnalysis },
27
+ } = core;
28
+
29
+ // Patch `formidable`
30
+ function install() {
31
+ depHooks.resolve({ name: 'formidable' }, (formidable) => {
32
+ formidable.IncomingForm.prototype.parse = patcher.patch(formidable.IncomingForm.prototype.parse, {
33
+ name: 'Formidable.IncomingForm.prototype.parse',
34
+ patchType,
35
+ pre(data) {
36
+ const origCb = data.args[1];
37
+
38
+ function hookedCb(...cbArgs) {
39
+ const sourceContext = protect.getSourceContext('formidable');
40
+
41
+ const [, fields, files] = cbArgs;
42
+
43
+ if (sourceContext) {
44
+ if (fields) {
45
+ sourceContext.parsedBody = fields;
46
+ inputAnalysis.handleParsedBody(sourceContext, fields);
47
+ }
48
+ if (files) {
49
+ logger.debug('Check for vulnerable filename upload nyi');
50
+ // TODO: NODE-2601
51
+ }
52
+ }
53
+
54
+ if (origCb && typeof origCb === 'function') {
55
+ origCb.apply(this, cbArgs);
56
+ }
57
+ }
58
+
59
+ data.args[1] = hookedCb;
60
+ }
61
+ });
62
+
63
+ return formidable;
64
+ });
65
+ }
66
+
67
+ const formidable1Instrumentation = inputAnalysis.formidable1Instrumentation = {
68
+ install
69
+ };
70
+
71
+ return formidable1Instrumentation;
72
+ };
@@ -1,3 +1,18 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
1
16
  'use strict';
2
17
 
3
18
  const { Event } = require('@contrast/common');
@@ -18,7 +33,6 @@ class HttpInstrumentation {
18
33
  this.config = core.config;
19
34
  this.logger = logger.child({ name: 'contrast:protect:input-analysis' });
20
35
  this.depHooks = core.depHooks;
21
- this.messages = core.messages;
22
36
  this.protect = core.protect;
23
37
  this.makeSourceContext = this.protect.makeSourceContext;
24
38
  this.maxBodySize = 16 * 1024 * 1024;
@@ -39,7 +53,9 @@ class HttpInstrumentation {
39
53
  this.hookHttps();
40
54
  }
41
55
 
42
- uninstall() {}
56
+ uninstall() {
57
+ return null; //NYI
58
+ }
43
59
 
44
60
  /**
45
61
  * Sets hooks to instrument `http.Server.prototype`.
@@ -149,6 +165,7 @@ class HttpInstrumentation {
149
165
  const connectInputs = {
150
166
  headers: HttpInstrumentation.removeCookies(reqData.headers),
151
167
  uriPath: reqData.uriPath,
168
+ rawUrl: req.url,
152
169
  // TODO AGENT-203 - need to handle method-tampering rule.
153
170
  method: reqData.method,
154
171
  };
@@ -157,9 +174,18 @@ class HttpInstrumentation {
157
174
  if (reqData.standardUrlParsing) {
158
175
  connectInputs.queries = reqData.queries;
159
176
  }
177
+ if (inputAnalysis.virtualPatchesEvaluators?.length) {
178
+ store.protect.virtualPatchesEvaluators.push(...inputAnalysis.virtualPatchesEvaluators.map((e) => new Map(e)));
179
+ }
180
+ if (inputAnalysis.ipDenylist?.length) {
181
+ block = inputAnalysis.handleIpDenylist(store.protect, inputAnalysis.ipDenylist);
182
+ }
183
+ if (inputAnalysis.ipAllowlist?.length) {
184
+ const allowed = inputAnalysis.handleIpAllowlist(store.protect, inputAnalysis.ipAllowlist);
185
+ if (!block) Object.assign(store.protect, { allowed });
186
+ }
160
187
 
161
- block = inputAnalysis.handleConnect(store.protect, connectInputs);
162
-
188
+ block = block || inputAnalysis.handleConnect(store.protect, connectInputs);
163
189
  } catch (err) {
164
190
  this.logger.error({ err }, 'Error during input analysis');
165
191
  }
@@ -0,0 +1,63 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const { patchType } = require('../constants');
19
+
20
+ module.exports = (core) => {
21
+ const {
22
+ depHooks,
23
+ patcher,
24
+ protect,
25
+ protect: { inputAnalysis },
26
+ } = core;
27
+
28
+ // Patch `koa-body` package
29
+ function install() {
30
+ depHooks.resolve({ name: 'koa-body' }, (koaBody) => patcher.patch(koaBody, {
31
+ name: 'koa-body',
32
+ patchType,
33
+ post(data) {
34
+ data.result = patcher.patch(data.result, {
35
+ name: 'koa-body',
36
+ patchType,
37
+ pre(data) {
38
+ const [ctx, origNext] = data.args;
39
+
40
+ async function contrastNext(origErr) {
41
+ const sourceContext = protect.getSourceContext('koa-body');
42
+
43
+ if (sourceContext && ctx.request.body && Object.keys(ctx.request.body).length) {
44
+ sourceContext.parsedBody = ctx.request.body;
45
+ inputAnalysis.handleParsedBody(sourceContext, ctx.request.body);
46
+ }
47
+
48
+ await origNext(origErr);
49
+ }
50
+
51
+ data.args[1] = contrastNext;
52
+ }
53
+ });
54
+ }
55
+ }));
56
+ }
57
+
58
+ const koaBody5Instrumentation = inputAnalysis.koaBody5Instrumentation = {
59
+ install
60
+ };
61
+
62
+ return koaBody5Instrumentation;
63
+ };
@@ -0,0 +1,64 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
16
+ 'use strict';
17
+
18
+ const { patchType } = require('../constants');
19
+
20
+ module.exports = (core) => {
21
+ const {
22
+ depHooks,
23
+ patcher,
24
+ protect,
25
+ protect: { inputAnalysis },
26
+ } = core;
27
+
28
+ // Patch `koa-bodyparser` package
29
+ function install() {
30
+ depHooks.resolve({ name: 'koa-bodyparser' }, (koaBodyparser) => patcher.patch(koaBodyparser, {
31
+ name: 'koa-bodyparser',
32
+ patchType,
33
+ post(data) {
34
+ data.result = patcher.patch(data.result, {
35
+ name: 'koa-bodyparser',
36
+ patchType,
37
+ pre(data) {
38
+ const [ctx, origNext] = data.args;
39
+
40
+ async function contrastNext(origErr) {
41
+ const sourceContext = protect.getSourceContext('koa-bodyparser');
42
+
43
+
44
+ if (sourceContext && ctx.request.body && Object.keys(ctx.request.body).length) {
45
+ sourceContext.parsedBody = ctx.request.body;
46
+ inputAnalysis.handleParsedBody(sourceContext, ctx.request.body);
47
+ }
48
+
49
+ await origNext(origErr);
50
+ }
51
+
52
+ data.args[1] = contrastNext;
53
+ }
54
+ });
55
+ }
56
+ }));
57
+ }
58
+
59
+ const koaBodyparser4Instrumentation = inputAnalysis.koaBodyparser4Instrumentation = {
60
+ install
61
+ };
62
+
63
+ return koaBodyparser4Instrumentation;
64
+ };
@@ -1,7 +1,24 @@
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
5
+
6
+ * NOTICE: This Software and the patented inventions embodied within may only be
7
+ * used as part of Contrast Security’s commercial offerings. Even though it is
8
+ * made available through public repositories, use of this Software is subject to
9
+ * the applicable End User Licensing Agreement found at
10
+ * https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
11
+ * between Contrast Security and the End User. The Software may not be reverse
12
+ * engineered, modified, repackaged, sold, redistributed or otherwise used in a
13
+ * way not consistent with the End User License Agreement.
14
+ */
15
+
1
16
  'use strict';
2
17
 
18
+ const { patchType } = require('../constants');
19
+
3
20
  /**
4
- * Function that exports an install method to patch Fastify framework with our instrumentation
21
+ * Function that exports an install method to patch Koa framework with our instrumentation
5
22
  * @param {Object} core - the core Contrast object in v5
6
23
  * @return {Object} object with install method and the other relative functions exported for testing purposes
7
24
  */
@@ -9,8 +26,7 @@ module.exports = (core) => {
9
26
  const {
10
27
  depHooks,
11
28
  patcher,
12
- logger,
13
- scopes: { sources },
29
+ protect,
14
30
  protect: { inputAnalysis },
15
31
  } = core;
16
32
 
@@ -19,25 +35,14 @@ module.exports = (core) => {
19
35
  */
20
36
  function install() {
21
37
  depHooks.resolve({ name: 'koa', version: '>=2.3.0' }, (Koa) => {
22
- const coBodyPatch = require('./co-body.js')(core);
23
- const multerPatch = require('./multer')(core);
24
- const formidablePatch = require('./formidable')(core);
25
- const qsPatch = require('./qs')(core);
26
- const cookieParserPatch = require('./cookie-parser')(core);
27
- const universalCookiePatch = require('./universal-cookie')(core);
28
-
29
-
30
38
  function contrastStartMiddleware(ctx, next) {
31
39
  if (ctx.query && Object.keys(ctx.query).length) {
32
- const sourceContext = sources.getStore()?.protect;
40
+ const sourceContext = protect.getSourceContext('Koa startMiddleware');
33
41
 
34
- if (!sourceContext) {
35
- logger.debug('source context not available in `qs` hook');
36
- } else if (!('parsedQuery' in sourceContext)) {
42
+ if (sourceContext && !('parsedQuery' in sourceContext)) {
37
43
  sourceContext.parsedQuery = ctx.query;
38
44
  inputAnalysis.handleQueryParams(sourceContext, ctx.query);
39
45
  }
40
-
41
46
  }
42
47
  return next();
43
48
  }
@@ -47,7 +52,7 @@ module.exports = (core) => {
47
52
 
48
53
  patcher.patch(Koa.prototype, 'use', {
49
54
  name: 'Koa.Application',
50
- patchType: 'framework-patch',
55
+ patchType,
51
56
  pre({ obj: app }) {
52
57
  // if not already inserted, insert the initial middleware.
53
58
  if (
@@ -66,17 +71,13 @@ module.exports = (core) => {
66
71
  (layer) => {
67
72
  layer.prototype = patcher.patch(layer.prototype, 'params', {
68
73
  name: `[${router}].layer.prototype`,
69
- patchType: 'framework-patch',
74
+ patchType,
70
75
  post({ result }) {
71
- const sourceContext = sources.getStore()?.protect;
72
-
73
- if (!sourceContext) {
74
- logger.debug(`source context not available in \`[${router}].layer\` hook`);
75
- } else {
76
- if (Object.keys(result).length) {
77
- sourceContext.parsedParams = result;
78
- inputAnalysis.handleUrlParams(sourceContext, result);
79
- }
76
+ const sourceContext = protect.getSourceContext(`[${router}].layer`);
77
+
78
+ if (sourceContext && Object.keys(result).length) {
79
+ sourceContext.parsedParams = result;
80
+ inputAnalysis.handleUrlParams(sourceContext, result);
80
81
  }
81
82
  }
82
83
  });
@@ -90,27 +91,23 @@ module.exports = (core) => {
90
91
  const { default: cookieParser } = koaCookie;
91
92
  koaCookie.default = patcher.patch(cookieParser, {
92
93
  name: 'koa-cookie',
93
- patchType: 'framework-patch',
94
+ patchType,
94
95
  post(data) {
95
96
  data.result = patcher.patch(data.result, {
96
97
  name: 'koa-cookie',
97
- patchType: 'framework-patch',
98
+ patchType,
98
99
  pre(data) {
99
100
  const [ctx, origNext] = data.args;
100
101
 
101
- async function contrastNext() {
102
- const sourceContext = sources.getStore()?.protect;
102
+ async function contrastNext(origErr) {
103
+ const sourceContext = protect.getSourceContext('koa-cookie');
103
104
 
104
- if (!sourceContext) {
105
- logger.debug('source context not available in `koa-cookie` hook');
106
- } else {
107
- if (ctx.cookie) {
108
- sourceContext.parsedCookies = ctx.cookie;
109
- inputAnalysis.handleCookies(sourceContext, ctx.cookie);
110
- }
105
+ if (sourceContext && ctx.cookie) {
106
+ sourceContext.parsedCookies = ctx.cookie;
107
+ inputAnalysis.handleCookies(sourceContext, ctx.cookie);
111
108
  }
112
109
 
113
- await origNext();
110
+ await origNext(origErr);
114
111
  }
115
112
 
116
113
  data.args[1] = contrastNext;
@@ -119,19 +116,12 @@ module.exports = (core) => {
119
116
  }
120
117
  });
121
118
  });
122
-
123
- coBodyPatch.install();
124
- multerPatch.install();
125
- formidablePatch.install();
126
- qsPatch.install();
127
- cookieParserPatch.install();
128
- universalCookiePatch.install();
129
119
  });
130
120
  }
131
121
 
132
- const koaInstrumentation = inputAnalysis.koaInstrumentation = {
122
+ const koa2Instrumentation = inputAnalysis.koa2Instrumentation = {
133
123
  install
134
124
  };
135
125
 
136
- return koaInstrumentation;
126
+ return koa2Instrumentation;
137
127
  };