@contrast/assess 1.18.0 → 1.19.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/constants.js +26 -0
  2. package/lib/crypto-analysis/common.js +20 -0
  3. package/lib/crypto-analysis/index.js +44 -0
  4. package/lib/crypto-analysis/install/crypto.js +151 -0
  5. package/lib/crypto-analysis/install/math.js +99 -0
  6. package/lib/dataflow/propagation/install/JSON/parse.js +12 -11
  7. package/lib/dataflow/propagation/install/JSON/stringify.js +1 -1
  8. package/lib/dataflow/propagation/install/ejs/escape-xml.js +2 -2
  9. package/lib/dataflow/propagation/install/ejs/index.js +1 -0
  10. package/lib/dataflow/propagation/install/ejs/template.js +77 -0
  11. package/lib/dataflow/propagation/install/util-format.js +9 -3
  12. package/lib/dataflow/sinks/install/child-process.js +20 -14
  13. package/lib/dataflow/sinks/install/eval.js +16 -14
  14. package/lib/dataflow/sinks/install/express/unvalidated-redirect.js +14 -8
  15. package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +12 -5
  16. package/lib/dataflow/sinks/install/fs.js +7 -7
  17. package/lib/dataflow/sinks/install/function.js +8 -12
  18. package/lib/dataflow/sinks/install/http/request.js +16 -8
  19. package/lib/dataflow/sinks/install/http/server-response.js +11 -2
  20. package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +15 -8
  21. package/lib/dataflow/sinks/install/libxmljs.js +15 -10
  22. package/lib/dataflow/sinks/install/marsdb.js +13 -8
  23. package/lib/dataflow/sinks/install/mongodb.js +25 -15
  24. package/lib/dataflow/sinks/install/mssql.js +20 -9
  25. package/lib/dataflow/sinks/install/mysql.js +15 -8
  26. package/lib/dataflow/sinks/install/node-serialize.js +15 -17
  27. package/lib/dataflow/sinks/install/postgres.js +17 -4
  28. package/lib/dataflow/sinks/install/sequelize.js +16 -9
  29. package/lib/dataflow/sinks/install/sqlite3.js +20 -7
  30. package/lib/dataflow/sinks/install/vm.js +19 -17
  31. package/lib/dataflow/sources/install/http.js +14 -42
  32. package/lib/dataflow/sources/install/koa/index.js +1 -0
  33. package/lib/dataflow/sources/install/koa/koa-multer.js +102 -0
  34. package/lib/dataflow/sources/install/multer1.js +25 -51
  35. package/lib/dataflow/sources/install/querystring.js +1 -4
  36. package/lib/event-factory.js +47 -0
  37. package/lib/get-policy.js +68 -0
  38. package/lib/get-source-context.js +62 -0
  39. package/lib/index.d.ts +50 -0
  40. package/lib/index.js +20 -19
  41. package/lib/make-source-context.js +74 -0
  42. package/lib/response-scanning/handlers/index.js +55 -28
  43. package/lib/response-scanning/install/http.js +13 -7
  44. package/lib/rule-scopes.js +48 -0
  45. package/lib/session-configuration/handlers.js +4 -3
  46. package/lib/session-configuration/install/express-session.js +8 -2
  47. package/package.json +2 -2
@@ -17,12 +17,17 @@
17
17
 
18
18
  const { split, substring, toLowerCase, trim } = require('@contrast/common');
19
19
 
20
+ /**
21
+ * @param {{
22
+ * assess: import('@contrast/assess').Assess,
23
+ * }} core
24
+ */
20
25
  module.exports = function(core) {
21
26
  const {
22
27
  depHooks,
23
28
  patcher,
24
- scopes: { sources },
25
29
  assess: {
30
+ getSourceContext,
26
31
  responseScanning: {
27
32
  handleAutoCompleteMissing,
28
33
  handleCacheControlsMissing,
@@ -36,6 +41,7 @@ module.exports = function(core) {
36
41
  }
37
42
  }
38
43
  } = core;
44
+
39
45
  const http = core.assess.responseScanning.httpInstrumentation = {};
40
46
 
41
47
  function parseHeaders(rawHeaders) {
@@ -90,7 +96,7 @@ module.exports = function(core) {
90
96
  name,
91
97
  patchType,
92
98
  post(data) {
93
- const sourceContext = sources.getStore()?.assess;
99
+ const sourceContext = getSourceContext();
94
100
  if (!sourceContext) return;
95
101
 
96
102
  const evaluationContext = {
@@ -108,7 +114,7 @@ module.exports = function(core) {
108
114
  name,
109
115
  patchType,
110
116
  post(data) {
111
- const sourceContext = sources.getStore()?.assess;
117
+ const sourceContext = getSourceContext();
112
118
  if (!sourceContext) return;
113
119
 
114
120
  const evaluationContext = {
@@ -130,7 +136,7 @@ module.exports = function(core) {
130
136
  name,
131
137
  patchType,
132
138
  post(data) {
133
- const sourceContext = sources.getStore()?.assess;
139
+ const sourceContext = getSourceContext();
134
140
  if (!sourceContext) return;
135
141
 
136
142
  const headersSymbol = Object.getOwnPropertySymbols(data.obj).find(symbol => symbol.toString().includes('headers'));
@@ -149,7 +155,7 @@ module.exports = function(core) {
149
155
  name,
150
156
  patchType,
151
157
  post(data) {
152
- const sourceContext = sources.getStore()?.assess;
158
+ const sourceContext = getSourceContext();
153
159
  if (!sourceContext) return;
154
160
 
155
161
  const headersSymbol = Object.getOwnPropertySymbols(data.result).find(symbol => symbol.toString().includes('headers'));
@@ -182,7 +188,7 @@ module.exports = function(core) {
182
188
  name: 'Http2Stream.write',
183
189
  patchType,
184
190
  post(data) {
185
- const sourceContext = sources.getStore()?.assess;
191
+ const sourceContext = getSourceContext();
186
192
  if (!sourceContext) return;
187
193
 
188
194
  const evaluationContext = {
@@ -198,7 +204,7 @@ module.exports = function(core) {
198
204
  name: 'Http2Stream.end',
199
205
  patchType,
200
206
  post(data) {
201
- const sourceContext = sources.getStore()?.assess;
207
+ const sourceContext = getSourceContext();
202
208
  if (!sourceContext) return;
203
209
 
204
210
  const evaluationContext = {
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Copyright: 2023 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 { AsyncLocalStorage } = require('async_hooks');
19
+ /**
20
+ * @param {Object} core
21
+ * @param {import('@contrast/assess').Assess} core.assess
22
+ */
23
+ module.exports = function (core) {
24
+
25
+ /** @type {Map<Rule,AsyncLocalStorage>} */
26
+ const scopes = new Map();
27
+ /** @type {{locked:boolean}}*/
28
+ const store = Object.freeze({ locked: true });
29
+
30
+ return core.assess.ruleScopes = {
31
+ /**
32
+ * @param {import('@contrast/common').Rule} ruleId
33
+ * @param {functionn} cb
34
+ */
35
+ run(ruleId, cb) {
36
+ if (!scopes.has(ruleId)) scopes.set(ruleId, new AsyncLocalStorage());
37
+ return scopes.get(ruleId).run(store, cb);
38
+ },
39
+
40
+ /**
41
+ * @param {Rule} ruleId
42
+ */
43
+ isLocked(ruleId) {
44
+ return !!scopes.get(ruleId)?.getStore?.()?.locked;
45
+ }
46
+ };
47
+
48
+ };
@@ -27,9 +27,10 @@ module.exports = function (core) {
27
27
  } = core;
28
28
 
29
29
  const checkCookieValue = (ruleId, sinkEvent, cookieValue, sourceContext) => {
30
- if (cookieValue.includes(ruleId === HTTPONLY ? 'httponly' : 'secure')) {
31
- return;
32
- }
30
+ if (
31
+ !sourceContext.policy?.enabledRules?.has(ruleId) ||
32
+ cookieValue.includes(ruleId === HTTPONLY ? 'httponly' : 'secure')
33
+ ) return;
33
34
 
34
35
  sessionConfiguration.reportFindings(sourceContext, {
35
36
  ruleId,
@@ -18,9 +18,16 @@ const util = require('util');
18
18
  const { toLowerCase } = require('@contrast/common');
19
19
  const { patchType } = require('../common');
20
20
 
21
+ /**
22
+ * @param {{
23
+ * assess: import('@contrast/assess').Assess,
24
+ * scopes: import('@contrast/scopes').Scopes,
25
+ * }} core
26
+ */
21
27
  module.exports = function (core) {
22
28
  const {
23
29
  assess: {
30
+ getSourceContext,
24
31
  eventFactory: { createSessionEvent },
25
32
  sessionConfiguration: {
26
33
  handleHttpOnly,
@@ -29,7 +36,6 @@ module.exports = function (core) {
29
36
  },
30
37
  depHooks,
31
38
  patcher,
32
- scopes: { sources },
33
39
  } = core;
34
40
 
35
41
  const expressSession = core.assess.sessionConfiguration.expressSession = {};
@@ -100,7 +106,7 @@ module.exports = function (core) {
100
106
  pre(data) {
101
107
  const [, res] = data.args;
102
108
 
103
- const sourceContext = sources.getStore()?.assess;
109
+ const sourceContext = getSourceContext();
104
110
  if (!sourceContext) return;
105
111
 
106
112
  patcher.patch(res, 'setHeader', {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contrast/assess",
3
- "version": "1.18.0",
3
+ "version": "1.19.0",
4
4
  "description": "Contrast service providing framework-agnostic Assess support",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
@@ -17,7 +17,7 @@
17
17
  "test": "../scripts/test.sh"
18
18
  },
19
19
  "dependencies": {
20
- "@contrast/common": "1.15.1",
20
+ "@contrast/common": "1.16.0",
21
21
  "@contrast/distringuish": "^4.4.0",
22
22
  "@contrast/scopes": "1.4.0"
23
23
  }