@contrast/protect 1.2.2 → 1.3.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 (47) hide show
  1. package/lib/cli-rewriter.js +15 -0
  2. package/lib/error-handlers/constants.js +15 -0
  3. package/lib/error-handlers/index.js +17 -0
  4. package/lib/error-handlers/install/express4.js +90 -0
  5. package/lib/error-handlers/install/fastify3.js +15 -0
  6. package/lib/error-handlers/install/koa2.js +15 -0
  7. package/lib/esm-loader.mjs +15 -0
  8. package/lib/index.d.ts +145 -19
  9. package/lib/index.js +15 -0
  10. package/lib/input-analysis/constants.js +20 -0
  11. package/lib/input-analysis/handlers.js +33 -10
  12. package/lib/input-analysis/index.js +36 -3
  13. package/lib/input-analysis/install/body-parser1.js +130 -0
  14. package/lib/input-analysis/install/cookie-parser1.js +82 -0
  15. package/lib/input-analysis/install/express4.js +108 -0
  16. package/lib/input-analysis/install/fastify3.js +47 -19
  17. package/lib/input-analysis/install/formidable1.js +73 -0
  18. package/lib/input-analysis/install/http.js +18 -1
  19. package/lib/input-analysis/install/koa-body5.js +68 -0
  20. package/lib/input-analysis/install/koa-bodyparser4.js +68 -0
  21. package/lib/input-analysis/install/koa2.js +26 -25
  22. package/lib/input-analysis/install/multer1.js +89 -0
  23. package/lib/input-analysis/install/qs6.js +61 -0
  24. package/lib/input-analysis/install/universal-cookie4.js +56 -0
  25. package/lib/input-tracing/constants.js +15 -0
  26. package/lib/input-tracing/handlers/index.js +154 -59
  27. package/lib/input-tracing/index.js +17 -0
  28. package/lib/input-tracing/install/child-process.js +16 -1
  29. package/lib/input-tracing/install/fs.js +17 -2
  30. package/lib/input-tracing/install/mongodb.js +233 -0
  31. package/lib/input-tracing/install/mysql.js +18 -2
  32. package/lib/input-tracing/install/postgres.js +15 -0
  33. package/lib/input-tracing/install/sequelize.js +15 -0
  34. package/lib/input-tracing/install/sqlite3.js +15 -0
  35. package/lib/make-response-blocker.js +15 -0
  36. package/lib/make-source-context.js +18 -0
  37. package/lib/security-exception.js +15 -0
  38. package/lib/throw-security-exception.js +17 -6
  39. package/lib/utils.js +14 -18
  40. package/package.json +8 -8
  41. package/lib/input-analysis/install/co-body.js +0 -51
  42. package/lib/input-analysis/install/cookie-parser.js +0 -48
  43. package/lib/input-analysis/install/formidable.js +0 -53
  44. package/lib/input-analysis/install/multer.js +0 -52
  45. package/lib/input-analysis/install/qs.js +0 -40
  46. package/lib/input-analysis/install/universal-cookie.js +0 -34
  47. package/lib/input-tracing/handlers/nosql-injection-mongo.js +0 -48
@@ -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 { isString } = require('@contrast/common');
@@ -68,7 +83,7 @@ module.exports = function(core) {
68
83
  patcher.patch(fs, method, {
69
84
  name,
70
85
  patchType,
71
- pre({ args, hooked, name }) {
86
+ pre({ args, hooked, name, orig }) {
72
87
  // don't proceed if instrumentation is off e.g. within require() call
73
88
  if (instrumentation.isLocked()) return;
74
89
 
@@ -86,7 +101,7 @@ module.exports = function(core) {
86
101
  for (const value of values) {
87
102
  const sinkContext = captureStacktrace(
88
103
  { name, value },
89
- { constructorOpt: hooked }
104
+ { constructorOpt: hooked, prependFrames: [orig] }
90
105
  );
91
106
  inputTracing.handlePathTraversal(sourceContext, sinkContext);
92
107
  }
@@ -0,0 +1,233 @@
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 semver = require('semver');
20
+
21
+ module.exports = function (core) {
22
+ const {
23
+ depHooks,
24
+ patcher,
25
+ scopes: { sources },
26
+ captureStacktrace,
27
+ protect: { inputTracing },
28
+ } = core;
29
+
30
+ function getCursorQueryData(args, version) {
31
+ const query = semver.gte(version, '3.3.0')
32
+ ? args[0]?.cmd?.query
33
+ : args[1]?.query;
34
+
35
+ if (!query) {
36
+ return;
37
+ }
38
+
39
+ if (Object.prototype.toString.call(query) === '[object String]') {
40
+ return query.toString();
41
+ }
42
+
43
+ if (query['$where']) {
44
+ return query['$where'].toString();
45
+ }
46
+
47
+ return query;
48
+ }
49
+
50
+ function getOpQueryData(op) {
51
+ if (!op.q) {
52
+ return;
53
+ }
54
+ if (op.q.$where) {
55
+ return op.q.$where;
56
+ }
57
+ return op.q;
58
+ }
59
+
60
+ function hookV3CommandAndCursor(obj, method, patchName, version) {
61
+ patcher.patch(obj, method, {
62
+ name: patchName,
63
+ patchType,
64
+ pre: ({ args, hooked, name }) => {
65
+ const value = getCursorQueryData(args, version);
66
+ const sourceContext = sources.getStore()?.protect;
67
+
68
+ if (!sourceContext || !value) return;
69
+
70
+ const sinkContext = captureStacktrace(
71
+ { name, value },
72
+ { constructorOpt: hooked }
73
+ );
74
+ inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
75
+ }
76
+ });
77
+ }
78
+
79
+ function hookV3UpdateAndRemove(obj, method, patchName) {
80
+ patcher.patch(obj, method, {
81
+ name: patchName,
82
+ patchType,
83
+ pre: ({ args, hooked, name }) => {
84
+ const sourceContext = sources.getStore()?.protect;
85
+ if (!sourceContext) return;
86
+
87
+
88
+ const ops = Array.isArray(args[1])
89
+ ? args[1]
90
+ : [args[1]];
91
+ for (const op of ops) {
92
+ const value = op && getOpQueryData(op);
93
+ if (value) {
94
+ const sinkContext = captureStacktrace(
95
+ { name, value },
96
+ { constructorOpt: hooked }
97
+ );
98
+ inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
99
+ }
100
+ }
101
+ },
102
+ });
103
+ }
104
+
105
+ function install() {
106
+ const v4MethodsWithFilter = [
107
+ 'updateOne',
108
+ 'replaceOne',
109
+ 'updateMany',
110
+ 'deleteOne',
111
+ 'deleteMany',
112
+ 'findOneAndDelete',
113
+ 'findOneAndReplace',
114
+ 'findOneAndUpdate',
115
+ 'countDocuments',
116
+ 'count',
117
+ 'distinct',
118
+ ];
119
+
120
+ depHooks.resolve(
121
+ {
122
+ name: 'mongodb', version: '>=4.0.0'
123
+ },
124
+ (mongodb) => {
125
+ v4MethodsWithFilter.forEach((method) => {
126
+ patcher.patch(mongodb.Collection.prototype, method, {
127
+ name: `mongodb.Collection.prototype.${method}`,
128
+ patchType,
129
+ pre: ({ args, hooked, name }) => {
130
+ const value = typeof args[0] == 'function' ? null : args[0];
131
+ const sourceContext = sources.getStore()?.protect;
132
+
133
+ if (!sourceContext || !value) return;
134
+
135
+ const sinkContext = captureStacktrace(
136
+ { name, value },
137
+ { constructorOpt: hooked }
138
+ );
139
+ inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
140
+ },
141
+ });
142
+ });
143
+
144
+ patcher.patch(mongodb.Db.prototype, 'command', {
145
+ name: 'mongodb.Db.prototype.command',
146
+ patchType,
147
+ pre: ({ args, hooked, name }) => {
148
+ const value = args[0]?.filter;
149
+ const sourceContext = sources.getStore()?.protect;
150
+
151
+ if (!sourceContext || !value) return;
152
+
153
+ const sinkContext = captureStacktrace(
154
+ { name, value },
155
+ { constructorOpt: hooked }
156
+ );
157
+ inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
158
+ }
159
+ });
160
+ });
161
+
162
+ depHooks.resolve(
163
+ {
164
+ name: 'mongodb', version: '<4.0.0'
165
+ }, (mongodb, { version }) => {
166
+ hookV3CommandAndCursor(mongodb.CoreServer.prototype, 'cursor', 'mongodb.CoreServer.prototype.cursor', version);
167
+
168
+ patcher.patch(mongodb.Db.prototype, 'eval', {
169
+ name: 'mongodb.Db.prototype.eval',
170
+ patchType,
171
+ pre: ({ args, hooked, name }) => {
172
+ const value = args[0];
173
+ const sourceContext = sources.getStore()?.protect;
174
+
175
+ if (!sourceContext || !value) return;
176
+
177
+ const sinkContext = captureStacktrace(
178
+ { name, value },
179
+ { constructorOpt: hooked }
180
+ );
181
+
182
+ inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
183
+ }
184
+ });
185
+ });
186
+
187
+ depHooks.resolve({ name: 'mongodb', file: 'lib/cursor/find_cursor', version: '>=4.0.0' }, (cursor) => patcher.patch(cursor, 'FindCursor', {
188
+ name: 'mongodb.FindCursor',
189
+ patchType,
190
+ pre: ({ args, hooked, name }) => {
191
+ const value = args[2];
192
+ const sourceContext = sources.getStore()?.protect;
193
+
194
+ if (!sourceContext || !value) return;
195
+
196
+ const sinkContext = captureStacktrace(
197
+ { name, value },
198
+ { constructorOpt: hooked }
199
+ );
200
+ inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
201
+ }
202
+ }));
203
+
204
+ const mongoDBTopologiesMethods = ['update', 'remove'];
205
+
206
+ depHooks.resolve({
207
+ name: 'mongodb',
208
+ file: 'lib/topologies/topology_base.js',
209
+ version: '<4.0.0'
210
+ }, (tpl, { version }) => {
211
+ mongoDBTopologiesMethods.forEach((method) => {
212
+ hookV3UpdateAndRemove(tpl.TopologyBase.prototype, method, `mongodb.TopologyBase.prototype.${method}`);
213
+ });
214
+ hookV3CommandAndCursor(tpl.TopologyBase.prototype, 'command', 'mongodb.TopologyBase.prototype.command', version);
215
+ });
216
+
217
+ depHooks.resolve({
218
+ name: 'mongodb',
219
+ file: 'lib/topologies/native_topology.js',
220
+ version: '<4.0.0'
221
+ }, (NativeTopology, { version }) => {
222
+ mongoDBTopologiesMethods.forEach((method) => {
223
+ hookV3UpdateAndRemove(NativeTopology.prototype, method, `mongodb.NativeTopology.prototype.${method}`);
224
+ });
225
+ hookV3CommandAndCursor(NativeTopology.prototype, 'command', 'mongodb.NativeTopology.prototype.command', version);
226
+ });
227
+ }
228
+ const mongodbInstr = (core.protect.inputTracing.mongodbInstrumentation = {
229
+ install,
230
+ });
231
+
232
+ return mongodbInstr;
233
+ };
@@ -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 { isString } = require('@contrast/common');
@@ -32,7 +47,8 @@ module.exports = function(core) {
32
47
  patcher.patch(conn.prototype, method, {
33
48
  name,
34
49
  patchType,
35
- pre({ args, hooked, name }) {
50
+ pre(data) {
51
+ const { args, hooked, name, orig } = data;
36
52
  const sourceContext = sources.getStore()?.protect;
37
53
  if (!sourceContext) return;
38
54
 
@@ -41,7 +57,7 @@ module.exports = function(core) {
41
57
 
42
58
  const sinkContext = captureStacktrace(
43
59
  { name, value },
44
- { constructorOpt: hooked }
60
+ { constructorOpt: hooked, prependFrames: [orig] }
45
61
  );
46
62
 
47
63
  inputTracing.handleSqlInjection(sourceContext, sinkContext);
@@ -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 { isString } = require('@contrast/common');
@@ -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 { isString } = require('@contrast/common');
@@ -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 { isString } = require('@contrast/common');
@@ -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
  module.exports = function(core) {
@@ -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
  module.exports = function(core) {
@@ -23,6 +38,7 @@ module.exports = function(core) {
23
38
  // lowercase header keys and capture content-type
24
39
  let contentType = '';
25
40
  const headers = Array(req.rawHeaders.length);
41
+
26
42
  for (let i = 0; i < req.rawHeaders.length; i += 2) {
27
43
  headers[i] = req.rawHeaders[i].toLowerCase();
28
44
  headers[i + 1] = req.rawHeaders[i + 1];
@@ -45,6 +61,8 @@ module.exports = function(core) {
45
61
  // so here is typically better; it makes clear what information is used to
46
62
  // make decisions by different handlers.
47
63
  const reqData = {
64
+ ip: req.socket.remoteAddress,
65
+ httpVersion: req.httpVersion,
48
66
  method: req.method,
49
67
  headers,
50
68
  uriPath,
@@ -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
  module.exports = class SecurityException extends Error {
@@ -1,6 +1,20 @@
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
- const Domain = require('async-hook-domain');
4
18
  const securityException = require('./security-exception');
5
19
 
6
20
  module.exports = function(core) {
@@ -17,12 +31,9 @@ module.exports = function(core) {
17
31
 
18
32
  const err = securityException.create();
19
33
 
20
- new Domain(() => {
21
- sourceContext.block(mode, ruleId);
22
- });
23
-
24
- logger.info({ err, mode, ruleId }, 'throwing security exception');
34
+ logger.debug({ err, mode, ruleId }, 'throwing security exception');
25
35
 
36
+ // TO-DO: NODE-2556 Research fail-safe handler for all security exceptions
26
37
  throw err;
27
38
  }
28
39
 
package/lib/utils.js CHANGED
@@ -1,22 +1,19 @@
1
- 'use strict';
1
+ /*
2
+ * Copyright: 2022 Contrast Security, Inc
3
+ * Contact: support@contrastsecurity.com
4
+ * License: Commercial
2
5
 
3
- /**
4
- * Get a symbol parameter value on the given object. The function should be
5
- * used with a `target` for which we are sure that the Symbol property we need is set before
6
- * any eventual duplicating Symbol properties. In case of duplicating Symbol properties
7
- * we will always get the one that's set first.
8
- * @param {Object} target built outgoing response
9
- * @param {String} symbolName full symbol stringified
10
- * @returns {Object} value of the requested symbol property
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.
11
14
  */
12
- function getSymbolProperty(target, symbolName) {
13
- if (!target) return;
14
- for (const sym of Object.getOwnPropertySymbols(target)) {
15
- if (sym.toString() === `Symbol(${symbolName})`) {
16
- return target[sym];
17
- }
18
- }
19
- }
15
+
16
+ 'use strict';
20
17
 
21
18
  /**
22
19
  * simpleTraverse() walks an object and calls a user function for each key
@@ -83,6 +80,5 @@ function simpleTraverse(obj, cb) {
83
80
  }
84
81
 
85
82
  module.exports = {
86
- getSymbolProperty,
87
83
  simpleTraverse,
88
84
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/protect",
3
- "version": "1.2.2",
3
+ "version": "1.3.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)",
@@ -13,7 +13,7 @@
13
13
  "contrast-transpile": "lib/cli-rewriter.js"
14
14
  },
15
15
  "engines": {
16
- "npm": ">=6.13.7 <7 || >= 8.3.1",
16
+ "npm": ">= 8.4.0",
17
17
  "node": ">= 14.15.0"
18
18
  },
19
19
  "scripts": {
@@ -23,11 +23,11 @@
23
23
  "@babel/template": "^7.16.7",
24
24
  "@babel/types": "^7.16.8",
25
25
  "@contrast/agent-lib": "^4.2.0",
26
- "@contrast/common": "1.0.2",
27
- "@contrast/core": "1.1.2",
28
- "@contrast/scopes": "1.0.2",
29
- "@contrast/esm-hooks": "1.1.2",
30
- "async-hook-domain": "^2.0.4",
31
- "builtin-modules": "^3.2.0"
26
+ "@contrast/common": "1.0.3",
27
+ "@contrast/core": "1.2.0",
28
+ "@contrast/scopes": "1.1.0",
29
+ "@contrast/esm-hooks": "1.1.3",
30
+ "builtin-modules": "^3.2.0",
31
+ "semver": "^7.3.7"
32
32
  }
33
33
  }
@@ -1,51 +0,0 @@
1
- 'use strict';
2
-
3
- module.exports = (core) => {
4
- const {
5
- depHooks,
6
- patcher,
7
- logger,
8
- scopes: { sources },
9
- protect: { inputAnalysis },
10
- } = core;
11
-
12
- async function postHook(data) {
13
- const { args: [, opts], result } = data;
14
- if (result) {
15
- const sourceContext = sources.getStore()?.protect;
16
- if (!sourceContext) {
17
- logger.debug('source context not available in `co-body` hook');
18
- } else {
19
- result.then((resolved) => {
20
- const parsedBody = opts?.returnRawBody ? resolved.parsed : resolved;
21
- sourceContext.parsedBody = parsedBody;
22
- inputAnalysis.handleParsedBody(sourceContext, parsedBody);
23
- });
24
- }
25
- }
26
- }
27
-
28
- return {
29
- // Patch lower level parser - `co-body` used by `koa-body` and `koa-bodyparser`
30
- install() {
31
- depHooks.resolve({ name: 'co-body' }, (coBody) => {
32
- coBody = patcher.patch(coBody, {
33
- name: 'co-body',
34
- patchType: 'framework-patch',
35
- post: postHook
36
- });
37
-
38
- ['json', 'form', 'text'].forEach((property) => {
39
- patcher.patch(coBody, property, {
40
- name: `co-body.${property}`,
41
- patchType: 'framework-patch',
42
- post: postHook
43
- });
44
- });
45
-
46
- return coBody;
47
- }
48
- );
49
- }
50
- };
51
- };
@@ -1,48 +0,0 @@
1
- 'use strict';
2
-
3
- module.exports = (core) => {
4
- const {
5
- depHooks,
6
- patcher,
7
- logger,
8
- scopes: { sources },
9
- protect: { inputAnalysis },
10
- } = core;
11
-
12
- return {
13
- // Patch `cookie-parser` package
14
- install() {
15
- depHooks.resolve({ name: 'cookie-parser' }, (cookieParser) => patcher.patch(cookieParser, {
16
- name: 'cookie-parser',
17
- patchType: 'framework-patch',
18
- post(data) {
19
- data.result = patcher.patch(data.result, {
20
- name: 'cookie-parser',
21
- patchType: 'framework-patch',
22
- pre(data) {
23
- const [req, , origNext] = data.args;
24
-
25
- async function contrastNext() {
26
- const sourceContext = sources.getStore()?.protect;
27
-
28
- if (!sourceContext) {
29
- logger.debug('source context not available in `cookie-parser` hook');
30
- } else {
31
- if (req.cookies) {
32
- sourceContext.parsedCookies = req.cookies;
33
- inputAnalysis.handleCookies(sourceContext, req.cookies);
34
- }
35
- }
36
-
37
- await origNext();
38
- }
39
-
40
- data.args[2] = contrastNext;
41
- }
42
- });
43
- }
44
- })
45
- );
46
- }
47
- };
48
- };