@contrast/protect 1.68.0 → 1.70.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.
@@ -28,7 +28,7 @@ module.exports = function(core) {
28
28
  require('./install/express')(core);
29
29
  require('./install/fastify')(core);
30
30
  require('./install/hapi')(core);
31
- require('./install/koa2')(core);
31
+ require('./install/koa')(core);
32
32
  require('./install/restify')(core);
33
33
 
34
34
  errorHandlers.install = function() {
@@ -27,10 +27,10 @@ module.exports = function (core) {
27
27
  protect,
28
28
  } = core;
29
29
 
30
- const koa2ErrorHandler = protect.errorHandlers.koa2ErrorHandler = {};
30
+ const koaErrorHandler = protect.errorHandlers.koaErrorHandler = {};
31
31
 
32
- koa2ErrorHandler.install = function () {
33
- depHooks.resolve({ name: 'koa', version: '>=2.3.0 <3' }, (Koa) => {
32
+ koaErrorHandler.install = function () {
33
+ depHooks.resolve({ name: 'koa', version: '>=2.3.0 <4' }, (Koa) => {
34
34
  patcher.patch(Koa.prototype, 'handleRequest', {
35
35
  name: 'Koa.Application.handleRequest',
36
36
  patchType,
@@ -63,5 +63,5 @@ module.exports = function (core) {
63
63
  });
64
64
  };
65
65
 
66
- return koa2ErrorHandler;
66
+ return koaErrorHandler;
67
67
  };
package/lib/index.d.ts CHANGED
@@ -122,7 +122,7 @@ export interface Protect {
122
122
  handler: (err: Error, request: IncomingMessage, reply: ServerResponse) => void,
123
123
  install: () => void
124
124
  }
125
- koa2ErrorHandler: { install: () => void },
125
+ koaErrorHandler: { install: () => void },
126
126
  expressErrorHandler: { install: () => void },
127
127
  install: () => void,
128
128
  },
@@ -665,7 +665,6 @@ module.exports = Core.makeComponent({
665
665
  // Detecting probes
666
666
  const rulesMask = sourceContext.policy.getRulesMask();
667
667
  if (rulesMask == 0 || !config.protect.probe_analysis.enable) return;
668
- const probeReports = [];
669
668
  const { resultsMap } = sourceContext;
670
669
  const probesRules = [Rule.CMD_INJECTION, Rule.PATH_TRAVERSAL, Rule.SQL_INJECTION, Rule.XXE];
671
670
  const probes = {};
@@ -734,7 +733,6 @@ module.exports = Core.makeComponent({
734
733
  }) || [];
735
734
  alibResult.forEach(result => {
736
735
  results.push({ value, ...result });
737
- probeReports.push({ value, ...result });
738
736
  valueToResultByRuleId[value] = resultByRuleId;
739
737
  });
740
738
  });
@@ -756,16 +754,7 @@ module.exports = Core.makeComponent({
756
754
  probes[key] = probe;
757
755
  });
758
756
 
759
- Object.values(probes).forEach(probe => {
760
- if (!resultsMap[probe.ruleId]) {
761
- resultsMap[probe.ruleId] = [];
762
- }
763
-
764
- resultsMap[probe.ruleId].push(probe);
765
- probeReports.push(probe);
766
- });
767
-
768
- for (const result of probeReports) {
757
+ for (const result of Object.values(probes)) {
769
758
  core.protect.reportFinding({ result });
770
759
  }
771
760
  };
@@ -30,15 +30,14 @@ module.exports = function(core) {
30
30
  require('./install/body-parser')(core);
31
31
  require('./install/cookie-parser1')(core);
32
32
  require('./install/formidable1')(core);
33
- require('./install/koa-body5')(core);
34
- require('./install/koa-bodyparser4')(core);
33
+ require('./install/koa-bodyparsers')(core);
35
34
  require('./install/multer1')(core);
36
35
  require('./install/qs6')(core);
37
36
  require('./install/universal-cookie4')(core);
38
37
 
39
38
  // framework specific instrumentation
40
39
  require('./install/fastify')(core);
41
- require('./install/koa2')(core);
40
+ require('./install/koa')(core);
42
41
  require('./install/express')(core);
43
42
  require('./install/hapi')(core);
44
43
  require('./install/restify')(core);
@@ -0,0 +1,92 @@
1
+ /*
2
+ * Copyright: 2025 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
+ function postFn(name) {
29
+ return function(data) {
30
+ data.result = patcher.patch(data.result, {
31
+ name,
32
+ patchType,
33
+ pre(data) {
34
+ const [ctx, origNext] = data.args;
35
+
36
+ async function contrastNext(origErr) {
37
+ const sourceContext = protect.getSourceContext();
38
+
39
+
40
+ if (sourceContext && ctx.request.body && Object.keys(ctx.request.body).length) {
41
+ sourceContext.parsedBody = ctx.request.body;
42
+ inputAnalysis.handleParsedBody(sourceContext, ctx.request.body);
43
+ }
44
+
45
+ await origNext(origErr);
46
+ }
47
+
48
+ data.args[1] = contrastNext;
49
+ }
50
+ });
51
+ };
52
+ }
53
+
54
+ function install() {
55
+ [['koa-body', '>=4 <6'], ['koa-bodyparser', '>=4 <5']].forEach(([name, version]) => {
56
+ depHooks.resolve({ name, version }, (koaBody) =>
57
+ patcher.patch(koaBody, {
58
+ name,
59
+ patchType,
60
+ post: postFn(name)
61
+ })
62
+ );
63
+ });
64
+
65
+ depHooks.resolve({ name: 'koa-body', version: '>=6 <7' }, (koaBody) =>
66
+ patcher.patch(koaBody, 'koaBody', {
67
+ name: 'koaBody',
68
+ patchType,
69
+ post: postFn('koa-body')
70
+ })
71
+ );
72
+
73
+ depHooks.resolve({ name: '@koa/bodyparser', version: '>=5 <7' }, (koaBody) => {
74
+ const patchedBodyParser = patcher.patch(koaBody.bodyParser, {
75
+ name: '@koa/bodyparser',
76
+ patchType,
77
+ post: postFn('@koa/bodyparser')
78
+ }
79
+ );
80
+ return {
81
+ default: patchedBodyParser,
82
+ bodyParser: patchedBodyParser
83
+ };
84
+ });
85
+ }
86
+
87
+ const koaBodyparserInstrumentation = inputAnalysis.koaBodyparserInstrumentation = {
88
+ install
89
+ };
90
+
91
+ return koaBodyparserInstrumentation;
92
+ };
@@ -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 <3' }, (Koa) => {
37
+ depHooks.resolve({ name: 'koa', version: '>=2.3.0 <4' }, (Koa) => {
38
38
  function contrastStartMiddleware(ctx, next) {
39
39
  if (ctx.query && Object.keys(ctx.query).length) {
40
40
  const sourceContext = protect.getSourceContext();
@@ -65,11 +65,11 @@ module.exports = (core) => {
65
65
  });
66
66
 
67
67
  // Patch `koa-router` and `@koa/router` to handle parsed params
68
- [['koa-router', '<14'], ['@koa/router', '<14']].forEach(([router, version]) => {
68
+ [['koa-router', '>=12 <15'], ['@koa/router', '>=12 <15']].forEach(([router, version]) => {
69
69
  depHooks.resolve(
70
70
  { name: router, version, file: 'lib/layer.js' },
71
71
  (layer) => {
72
- layer.prototype = patcher.patch(layer.prototype, 'params', {
72
+ patcher.patch(layer.prototype, 'params', {
73
73
  name: `[${router}].layer.prototype`,
74
74
  patchType,
75
75
  post({ result }) {
@@ -119,9 +119,9 @@ module.exports = (core) => {
119
119
  });
120
120
  }
121
121
 
122
- const koa2Instrumentation = inputAnalysis.koa2Instrumentation = {
122
+ const koaInstrumentation = inputAnalysis.koaInstrumentation = {
123
123
  install
124
124
  };
125
125
 
126
- return koa2Instrumentation;
126
+ return koaInstrumentation;
127
127
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/protect",
3
- "version": "1.68.0",
3
+ "version": "1.70.0",
4
4
  "description": "Contrast service providing framework-agnostic Protect support",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -21,16 +21,16 @@
21
21
  },
22
22
  "dependencies": {
23
23
  "@contrast/agent-lib": "^9.1.0",
24
- "@contrast/common": "1.37.0",
25
- "@contrast/config": "1.52.1",
26
- "@contrast/core": "1.57.1",
27
- "@contrast/dep-hooks": "1.26.1",
28
- "@contrast/esm-hooks": "2.32.0",
29
- "@contrast/instrumentation": "1.36.1",
30
- "@contrast/logger": "1.30.1",
31
- "@contrast/patcher": "1.29.1",
32
- "@contrast/rewriter": "1.34.0",
33
- "@contrast/scopes": "1.27.1",
24
+ "@contrast/common": "1.38.0",
25
+ "@contrast/config": "1.54.0",
26
+ "@contrast/core": "1.59.0",
27
+ "@contrast/dep-hooks": "1.28.0",
28
+ "@contrast/esm-hooks": "2.34.0",
29
+ "@contrast/instrumentation": "1.38.0",
30
+ "@contrast/logger": "1.32.0",
31
+ "@contrast/patcher": "1.31.0",
32
+ "@contrast/rewriter": "1.36.0",
33
+ "@contrast/scopes": "1.29.0",
34
34
  "async-hook-domain": "^4.0.1",
35
35
  "ipaddr.js": "^2.0.1",
36
36
  "on-finished": "^2.4.1",
@@ -1,63 +0,0 @@
1
- /*
2
- * Copyright: 2025 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', version: '<7' }, (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();
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
- };
@@ -1,64 +0,0 @@
1
- /*
2
- * Copyright: 2025 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', version: '<5' }, (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();
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
- };