@contrast/assess 1.35.0 → 1.37.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 (169) hide show
  1. package/lib/crypto-analysis/install/crypto.js +1 -1
  2. package/lib/dataflow/propagation/install/JSON/parse-fn.js +1 -1
  3. package/lib/dataflow/propagation/install/JSON/parse.js +3 -2
  4. package/lib/dataflow/propagation/install/JSON/parse.test.js +2 -2
  5. package/lib/dataflow/propagation/install/JSON/stringify.js +11 -10
  6. package/lib/dataflow/propagation/install/JSON/stringify.test.js +3 -3
  7. package/lib/dataflow/propagation/install/array-prototype-join.js +4 -3
  8. package/lib/dataflow/propagation/install/array-prototype-join.test.js +3 -3
  9. package/lib/dataflow/propagation/install/buffer.js +2 -3
  10. package/lib/dataflow/propagation/install/contrast-methods/tag.test.js +2 -2
  11. package/lib/dataflow/propagation/install/decode-uri-component.js +5 -8
  12. package/lib/dataflow/propagation/install/decode-uri-component.test.js +1 -1
  13. package/lib/dataflow/propagation/install/ejs/escape-xml.js +6 -9
  14. package/lib/dataflow/propagation/install/ejs/escape-xml.test.js +2 -2
  15. package/lib/dataflow/propagation/install/ejs/template.js +2 -2
  16. package/lib/dataflow/propagation/install/encode-uri.js +4 -6
  17. package/lib/dataflow/propagation/install/encode-uri.test.js +2 -2
  18. package/lib/dataflow/propagation/install/escape-html.js +5 -8
  19. package/lib/dataflow/propagation/install/escape-html.test.js +3 -3
  20. package/lib/dataflow/propagation/install/escape.js +5 -8
  21. package/lib/dataflow/propagation/install/escape.test.js +2 -2
  22. package/lib/dataflow/propagation/install/fastify-send.js +3 -5
  23. package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +6 -9
  24. package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.test.js +1 -1
  25. package/lib/dataflow/propagation/install/joi/boolean.js +50 -52
  26. package/lib/dataflow/propagation/install/joi/expression.js +3 -10
  27. package/lib/dataflow/propagation/install/joi/index.js +98 -101
  28. package/lib/dataflow/propagation/install/joi/keys.js +10 -5
  29. package/lib/dataflow/propagation/install/joi/number.js +50 -52
  30. package/lib/dataflow/propagation/install/joi/string-schema.js +9 -14
  31. package/lib/dataflow/propagation/install/joi/utils.js +7 -4
  32. package/lib/dataflow/propagation/install/joi/values.js +5 -7
  33. package/lib/dataflow/propagation/install/mongoose/schema-map.js +5 -4
  34. package/lib/dataflow/propagation/install/mongoose/schema-map.test.js +4 -4
  35. package/lib/dataflow/propagation/install/mongoose/schema-mixed.js +5 -4
  36. package/lib/dataflow/propagation/install/mongoose/schema-mixed.test.js +4 -5
  37. package/lib/dataflow/propagation/install/mongoose/schema-string.js +99 -5
  38. package/lib/dataflow/propagation/install/mongoose/schema-string.test.js +41 -2
  39. package/lib/dataflow/propagation/install/mustache-escape.js +5 -8
  40. package/lib/dataflow/propagation/install/mustache-escape.test.js +2 -2
  41. package/lib/dataflow/propagation/install/mysql-connection-escape.js +5 -8
  42. package/lib/dataflow/propagation/install/mysql-connection-escape.test.js +2 -2
  43. package/lib/dataflow/propagation/install/parse-int.js +3 -3
  44. package/lib/dataflow/propagation/install/path/basename.js +7 -12
  45. package/lib/dataflow/propagation/install/path/basename.test.js +2 -2
  46. package/lib/dataflow/propagation/install/path/common.js +2 -2
  47. package/lib/dataflow/propagation/install/path/dirname.js +5 -10
  48. package/lib/dataflow/propagation/install/path/dirname.test.js +2 -2
  49. package/lib/dataflow/propagation/install/path/extname.js +6 -11
  50. package/lib/dataflow/propagation/install/path/extname.test.js +2 -2
  51. package/lib/dataflow/propagation/install/path/format.js +7 -13
  52. package/lib/dataflow/propagation/install/path/format.test.js +2 -2
  53. package/lib/dataflow/propagation/install/path/join-and-resolve.js +7 -12
  54. package/lib/dataflow/propagation/install/path/join-and-resolve.test.js +2 -2
  55. package/lib/dataflow/propagation/install/path/normalize.js +4 -11
  56. package/lib/dataflow/propagation/install/path/normalize.test.js +2 -2
  57. package/lib/dataflow/propagation/install/path/parse.js +3 -8
  58. package/lib/dataflow/propagation/install/path/parse.test.js +2 -2
  59. package/lib/dataflow/propagation/install/path/relative.js +5 -11
  60. package/lib/dataflow/propagation/install/path/relative.test.js +2 -2
  61. package/lib/dataflow/propagation/install/path/toNamespacedPath.js +5 -11
  62. package/lib/dataflow/propagation/install/path/toNamespacedPath.test.js +2 -2
  63. package/lib/dataflow/propagation/install/pug/index.js +8 -3
  64. package/lib/dataflow/propagation/install/pug-runtime-escape.js +5 -8
  65. package/lib/dataflow/propagation/install/pug-runtime-escape.test.js +1 -1
  66. package/lib/dataflow/propagation/install/querystring/escape.js +3 -3
  67. package/lib/dataflow/propagation/install/querystring/parse.js +7 -11
  68. package/lib/dataflow/propagation/install/querystring/stringify.js +3 -3
  69. package/lib/dataflow/propagation/install/reg-exp-prototype-exec.js +4 -3
  70. package/lib/dataflow/propagation/install/reg-exp-prototype-exec.test.js +5 -3
  71. package/lib/dataflow/propagation/install/send.js +5 -10
  72. package/lib/dataflow/propagation/install/sequelize/query-generator.js +3 -4
  73. package/lib/dataflow/propagation/install/sequelize/sql-string.js +8 -12
  74. package/lib/dataflow/propagation/install/sequelize/sql-string.test.js +2 -13
  75. package/lib/dataflow/propagation/install/sql-template-strings.js +3 -5
  76. package/lib/dataflow/propagation/install/sql-template-strings.test.js +2 -2
  77. package/lib/dataflow/propagation/install/string/concat.js +2 -1
  78. package/lib/dataflow/propagation/install/string/concat.test.js +15 -2
  79. package/lib/dataflow/propagation/install/string/format-methods.js +4 -2
  80. package/lib/dataflow/propagation/install/string/format-methods.test.js +15 -2
  81. package/lib/dataflow/propagation/install/string/html-methods.js +1 -1
  82. package/lib/dataflow/propagation/install/string/html-methods.test.js +15 -2
  83. package/lib/dataflow/propagation/install/string/index.js +2 -2
  84. package/lib/dataflow/propagation/install/string/match-all.js +2 -1
  85. package/lib/dataflow/propagation/install/string/match-all.test.js +13 -0
  86. package/lib/dataflow/propagation/install/string/match.js +11 -10
  87. package/lib/dataflow/propagation/install/string/match.test.js +13 -0
  88. package/lib/dataflow/propagation/install/string/replace.js +15 -9
  89. package/lib/dataflow/propagation/install/string/replace.test.js +13 -0
  90. package/lib/dataflow/propagation/install/string/slice.js +2 -1
  91. package/lib/dataflow/propagation/install/string/slice.test.js +13 -0
  92. package/lib/dataflow/propagation/install/string/split.js +2 -1
  93. package/lib/dataflow/propagation/install/string/split.test.js +13 -0
  94. package/lib/dataflow/propagation/install/string/substring.js +2 -1
  95. package/lib/dataflow/propagation/install/string/substring.test.js +13 -0
  96. package/lib/dataflow/propagation/install/string/trim.js +4 -1
  97. package/lib/dataflow/propagation/install/string/trim.test.js +13 -0
  98. package/lib/dataflow/propagation/install/unescape.js +5 -8
  99. package/lib/dataflow/propagation/install/unescape.test.js +2 -2
  100. package/lib/dataflow/propagation/install/url/domain-parsers.js +4 -5
  101. package/lib/dataflow/propagation/install/url/domain-parsers.test.js +2 -2
  102. package/lib/dataflow/propagation/install/url/parse.js +3 -2
  103. package/lib/dataflow/propagation/install/url/parse.test.js +2 -2
  104. package/lib/dataflow/propagation/install/url/searchParams.js +5 -5
  105. package/lib/dataflow/propagation/install/url/searchParams.test.js +2 -2
  106. package/lib/dataflow/propagation/install/url/url.js +6 -3
  107. package/lib/dataflow/propagation/install/url/url.test.js +2 -2
  108. package/lib/dataflow/propagation/install/util-format.js +7 -6
  109. package/lib/dataflow/propagation/install/util-format.test.js +2 -2
  110. package/lib/dataflow/propagation/install/validator/hooks.js +7 -2
  111. package/lib/dataflow/sinks/install/child-process.js +1 -1
  112. package/lib/dataflow/sinks/install/child-process.test.js +1 -1
  113. package/lib/dataflow/sinks/install/fs.js +1 -1
  114. package/lib/dataflow/sinks/install/fs.test.js +1 -1
  115. package/lib/dataflow/sinks/install/function.js +1 -1
  116. package/lib/dataflow/sinks/install/http/request.js +2 -1
  117. package/lib/dataflow/sinks/install/http/request.test.js +1 -1
  118. package/lib/dataflow/sinks/install/http/server-response.test.js +3 -5
  119. package/lib/dataflow/sinks/install/restify.js +1 -1
  120. package/lib/dataflow/sinks/install/vm.js +4 -2
  121. package/lib/dataflow/sinks/install/vm.test.js +1 -1
  122. package/lib/dataflow/sources/handler.js +5 -2
  123. package/lib/dataflow/sources/install/body-parser1.test.js +4 -4
  124. package/lib/dataflow/sources/install/busboy.js +8 -3
  125. package/lib/dataflow/sources/install/busboy.test.js +2 -2
  126. package/lib/dataflow/sources/install/cookie-parser1.test.js +2 -2
  127. package/lib/dataflow/sources/install/express/params.js +14 -11
  128. package/lib/dataflow/sources/install/express/params.test.js +5 -7
  129. package/lib/dataflow/sources/install/express/parsedUrl.js +3 -2
  130. package/lib/dataflow/sources/install/fastify/fastify.js +7 -6
  131. package/lib/dataflow/sources/install/fastify/fastify.test.js +2 -2
  132. package/lib/dataflow/sources/install/formidable1.js +7 -6
  133. package/lib/dataflow/sources/install/formidable1.test.js +2 -2
  134. package/lib/dataflow/sources/install/hapi/hapi.js +8 -10
  135. package/lib/dataflow/sources/install/hapi/hapi.test.js +0 -1
  136. package/lib/dataflow/sources/install/http.js +20 -16
  137. package/lib/dataflow/sources/install/http.test.js +28 -34
  138. package/lib/dataflow/sources/install/koa/koa-bodyparsers.js +7 -7
  139. package/lib/dataflow/sources/install/koa/koa-bodyparsers.test.js +3 -4
  140. package/lib/dataflow/sources/install/koa/koa-multer.js +8 -4
  141. package/lib/dataflow/sources/install/koa/koa-routers.js +7 -6
  142. package/lib/dataflow/sources/install/koa/koa-routers.test.js +2 -2
  143. package/lib/dataflow/sources/install/koa/koa2.js +7 -3
  144. package/lib/dataflow/sources/install/koa/koa2.test.js +1 -1
  145. package/lib/dataflow/sources/install/multer1.js +6 -2
  146. package/lib/dataflow/sources/install/qs6.js +1 -1
  147. package/lib/dataflow/sources/install/querystring.js +1 -1
  148. package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.js +1 -4
  149. package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.test.js +6 -8
  150. package/lib/dataflow/sources/install/restify/jsonBodyParser.js +0 -1
  151. package/lib/dataflow/sources/install/restify/jsonBodyParser.test.js +4 -8
  152. package/lib/dataflow/sources/install/restify/router.test.js +2 -2
  153. package/lib/dataflow/tag-utils.js +1 -1
  154. package/lib/dataflow/tracker.js +1 -1
  155. package/lib/dataflow/utils/is-safe-content-type.js +3 -2
  156. package/lib/event-factory.js +4 -4
  157. package/lib/get-policy.js +2 -2
  158. package/lib/index.js +18 -7
  159. package/lib/index.test.js +4 -0
  160. package/lib/make-source-context.js +37 -28
  161. package/lib/make-source-context.test.js +7 -7
  162. package/lib/response-scanning/handlers/index.js +7 -5
  163. package/lib/response-scanning/handlers/utils.js +11 -8
  164. package/lib/response-scanning/install/http.js +1 -1
  165. package/lib/sampler.js +136 -0
  166. package/lib/sampler.test.js +296 -0
  167. package/lib/session-configuration/install/express-session.js +1 -1
  168. package/lib/session-configuration/install/fastify-cookie.js +1 -1
  169. package/package.json +10 -10
@@ -6,6 +6,7 @@ const { initAssessFixture } = require('@contrast/test/fixtures');
6
6
 
7
7
  describe('assess dataflow propagation string slice', function () {
8
8
  let core, tracker, trackString, simulateRequestScope;
9
+ const allPatcher = new Map();
9
10
 
10
11
  beforeEach(function () {
11
12
  ({
@@ -23,6 +24,18 @@ describe('assess dataflow propagation string slice', function () {
23
24
  sinon.resetHistory();
24
25
  });
25
26
 
27
+ // eslint-disable-next-line mocha/no-sibling-hooks
28
+ afterEach(function() {
29
+ core.Perf.fromAllToMap('patcher', allPatcher);
30
+ });
31
+
32
+ after(function() {
33
+ const stats = core.Perf.getStats(allPatcher);
34
+ for (const [key, { n, totalMicros, mean }] of stats.entries()) {
35
+ console.log(key, n, totalMicros, 'nsec', mean, 'mean');
36
+ }
37
+ });
38
+
26
39
  [
27
40
  {
28
41
  desc: 'not tracked',
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { ArrayPrototypeJoin } = require('@contrast/common');
18
+ const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common');
19
19
  const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants');
20
20
  const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils');
21
21
  const { patchType } = require('../../common');
@@ -37,6 +37,7 @@ module.exports = function(core) {
37
37
  patcher.patch(String.prototype, 'split', {
38
38
  name,
39
39
  patchType,
40
+ usePerf: true,
40
41
  post(data) {
41
42
  const { name, args: origArgs, obj, result, hooked, orig } = data;
42
43
  if (
@@ -6,6 +6,7 @@ const { initAssessFixture } = require('@contrast/test/fixtures');
6
6
 
7
7
  describe('assess dataflow propagation string split', function () {
8
8
  let core, simulateRequestScope, trackString, tracker;
9
+ const allPatcher = new Map();
9
10
 
10
11
  beforeEach(function () {
11
12
  ({
@@ -27,6 +28,18 @@ describe('assess dataflow propagation string split', function () {
27
28
  core.assess.dataflow.propagation.stringInstrumentation.split.uninstall();
28
29
  });
29
30
 
31
+ // eslint-disable-next-line mocha/no-sibling-hooks
32
+ afterEach(function() {
33
+ core.Perf.fromAllToMap('patcher', allPatcher);
34
+ });
35
+
36
+ after(function() {
37
+ const stats = core.Perf.getStats(allPatcher);
38
+ for (const [key, { n, totalMicros, mean }] of stats.entries()) {
39
+ console.log(key, n, totalMicros, 'nsec', mean, 'mean');
40
+ }
41
+ });
42
+
30
43
  describe('base cases', function () {
31
44
  it('normal split on non-tracked string', function () {
32
45
  simulateRequestScope(() => {
@@ -15,7 +15,7 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { ArrayPrototypeJoin } = require('@contrast/common');
18
+ const { primordials: { ArrayPrototypeJoin } } = require('@contrast/common');
19
19
  const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants');
20
20
  const { createSubsetTags, getAdjustedUntrackedValue } = require('../../../tag-utils');
21
21
  const { patchType } = require('../../common');
@@ -62,6 +62,7 @@ module.exports = function(core) {
62
62
  patcher.patch(String.prototype, method, {
63
63
  name: `String.prototype.${method}`,
64
64
  patchType,
65
+ usePerf: true,
65
66
  post(data) {
66
67
  const { obj, args: origArgs, result, name, hooked, orig } = data;
67
68
  if (!result || !getSourceContext(PROPAGATOR)) return;
@@ -6,6 +6,7 @@ const { initAssessFixture } = require('@contrast/test/fixtures');
6
6
 
7
7
  describe('assess dataflow propagation string substring', function () {
8
8
  let core, tracker, trackString, simulateRequestScope;
9
+ const allPatcher = new Map();
9
10
 
10
11
  beforeEach(function () {
11
12
  ({
@@ -23,6 +24,18 @@ describe('assess dataflow propagation string substring', function () {
23
24
  sinon.resetHistory();
24
25
  });
25
26
 
27
+ // eslint-disable-next-line mocha/no-sibling-hooks
28
+ afterEach(function() {
29
+ core.Perf.fromAllToMap('patcher', allPatcher);
30
+ });
31
+
32
+ after(function() {
33
+ const stats = core.Perf.getStats(allPatcher);
34
+ for (const [key, { n, totalMicros, mean }] of stats.entries()) {
35
+ console.log(key, n, totalMicros, 'nsec', mean, 'mean');
36
+ }
37
+ });
38
+
26
39
  [
27
40
  {
28
41
  desc: 'below',
@@ -92,18 +92,21 @@ module.exports = function(core) {
92
92
  name: 'String.prototype.trim',
93
93
  patchType,
94
94
  post: createPostHook('trim'),
95
+ usePerf: true,
95
96
  });
96
97
 
97
98
  patcher.patch(String.prototype, 'trimStart', {
98
99
  name: 'String.prototype.trimStart',
99
100
  patchType,
100
- post: createPostHook('trimStart')
101
+ post: createPostHook('trimStart'),
102
+ usePerf: true,
101
103
  });
102
104
 
103
105
  patcher.patch(String.prototype, 'trimEnd', {
104
106
  name: 'String.prototype.trimEnd',
105
107
  patchType,
106
108
  post: createPostHook('trimEnd', 0),
109
+ usePerf: true,
107
110
  });
108
111
  },
109
112
  uninstall() {
@@ -6,6 +6,7 @@ const { initAssessFixture } = require('@contrast/test/fixtures');
6
6
 
7
7
  describe('assess dataflow propagation string trim', function () {
8
8
  let core, tracker, trackString, simulateRequestScope;
9
+ const allPatcher = new Map();
9
10
 
10
11
  beforeEach(function () {
11
12
  ({
@@ -23,6 +24,18 @@ describe('assess dataflow propagation string trim', function () {
23
24
  sinon.resetHistory();
24
25
  });
25
26
 
27
+ // eslint-disable-next-line mocha/no-sibling-hooks
28
+ afterEach(function() {
29
+ core.Perf.fromAllToMap('patcher', allPatcher);
30
+ });
31
+
32
+ after(function() {
33
+ const stats = core.Perf.getStats(allPatcher);
34
+ for (const [key, { n, totalMicros, mean }] of stats.entries()) {
35
+ console.log(key, n, totalMicros, 'nsec', mean, 'mean');
36
+ }
37
+ });
38
+
26
39
  [
27
40
  {
28
41
  str: 'not-tracked',
@@ -15,19 +15,16 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const {
19
- DataflowTag: { WEAK_URL_ENCODED }
20
- } = require('@contrast/common');
21
- const {
22
- createFullLengthCopyTags
23
- } = require('../../tag-utils');
18
+ const { DataflowTag: { WEAK_URL_ENCODED } } = require('@contrast/common');
19
+ const { InstrumentationType: { PROPAGATOR } } = require('../../../constants');
20
+ const { createFullLengthCopyTags } = require('../../tag-utils');
24
21
  const { patchType, createObjectLabel } = require('../common');
25
22
 
26
23
  module.exports = function(core) {
27
24
  const {
28
- scopes: { sources, instrumentation },
29
25
  patcher,
30
26
  assess: {
27
+ getSourceContext,
31
28
  eventFactory: { createPropagationEvent },
32
29
  dataflow: { tracker }
33
30
  }
@@ -42,7 +39,7 @@ module.exports = function(core) {
42
39
  patchType,
43
40
  post(data) {
44
41
  const { args, result, hooked, orig } = data;
45
- if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
42
+ if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return;
46
43
 
47
44
  const argInfo = tracker.getData(args[0]);
48
45
 
@@ -58,12 +58,12 @@ describe('assess dataflow propagation unescape', function () {
58
58
  });
59
59
  });
60
60
 
61
- it('will not propagate if there is no assess context', function () {
61
+ it('will not propagate if there is no assess policy in request context', function () {
62
62
  simulateRequestScope(function () {
63
63
  const value = trackString('%3Ftest%3Dstr');
64
64
  const result = unescape(value);
65
65
  expect(tracker.getData(result)).to.be.null;
66
- }, {});
66
+ }, { assess: { policy: null } });
67
67
  });
68
68
 
69
69
  it('will not propagate if there instrumentation is locked', function () {
@@ -15,17 +15,16 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const {
19
- createFullLengthCopyTags
20
- } = require('../../../tag-utils');
18
+ const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants');
19
+ const { createFullLengthCopyTags } = require('../../../tag-utils');
21
20
  const { patchType, createModuleLabel } = require('../../common');
22
21
 
23
22
  module.exports = function(core) {
24
23
  const {
25
- scopes: { sources, instrumentation },
26
24
  patcher,
27
25
  depHooks,
28
26
  assess: {
27
+ getSourceContext,
29
28
  eventFactory: { createPropagationEvent },
30
29
  dataflow: { tracker }
31
30
  }
@@ -42,7 +41,7 @@ module.exports = function(core) {
42
41
  patchType,
43
42
  post(data) {
44
43
  const { args, result, hooked, orig } = data;
45
- if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
44
+ if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return;
46
45
 
47
46
  const argInfo = tracker.getData(args[0]);
48
47
 
@@ -43,12 +43,12 @@ describe('assess dataflow propagation url domain-parsers', function () {
43
43
  });
44
44
  });
45
45
 
46
- it('will not propagate if there is no assess context', function () {
46
+ it('will not propagate if there is no assess store in request context', function () {
47
47
  simulateRequestScope(function () {
48
48
  const value = trackString('foo');
49
49
  const result = url.domainToASCII(value);
50
50
  expect(tracker.getData(result)).to.be.null;
51
- }, {});
51
+ }, { assess: { policy: null } });
52
52
  });
53
53
 
54
54
  it('will not propagate if there instrumentation is locked', function () {
@@ -15,14 +15,15 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants');
18
19
  const { patchType } = require('../../common');
19
20
 
20
21
  module.exports = function(core) {
21
22
  const {
22
- scopes: { sources, instrumentation },
23
23
  patcher,
24
24
  depHooks,
25
25
  assess: {
26
+ getSourceContext,
26
27
  inspect, // todo: remove
27
28
  eventFactory: { createPropagationEvent },
28
29
  dataflow: { tracker }
@@ -88,7 +89,7 @@ module.exports = function(core) {
88
89
  patchType,
89
90
  post(data) {
90
91
  const { args, result, hooked, orig } = data;
91
- if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
92
+ if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return;
92
93
 
93
94
  const [url, parseQueryString] = args;
94
95
  const argInfo = tracker.getData(url);
@@ -67,14 +67,14 @@ describe('assess dataflow propagation url.parse', function () {
67
67
  });
68
68
  });
69
69
 
70
- it('will not propagate if there is no assess context', function () {
70
+ it('will not propagate if there is no assess policy in request context', function () {
71
71
  simulateRequestScope(function () {
72
72
  const value = trackString('foo');
73
73
  const result = new url.parse('http://'.concat(value, ':3000/path'));
74
74
  keys.forEach((key) => {
75
75
  expect(tracker.getData(result[key])).to.be.null;
76
76
  });
77
- }, {});
77
+ }, { assess: { policy: null } });
78
78
  });
79
79
 
80
80
  it('will not propagate if there instrumentation is locked', function () {
@@ -15,17 +15,18 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { patchType } = require('../../common');
19
- const { isString, StringPrototypeConcat, StringPrototypeReplaceAll } = require('@contrast/common');
18
+ const { isString, primordials: { StringPrototypeConcat, StringPrototypeReplaceAll } } = require('@contrast/common');
19
+ const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants');
20
20
  const { createAppendTags } = require('../../../tag-utils');
21
+ const { patchType } = require('../../common');
21
22
 
22
23
  module.exports = function(core) {
23
24
  const {
24
- scopes: { sources, instrumentation },
25
25
  patcher,
26
26
  depHooks,
27
27
  assess: {
28
28
  inspect, // todo: remove
29
+ getSourceContext,
29
30
  eventFactory: { createPropagationEvent },
30
31
  dataflow: { tracker }
31
32
  }
@@ -60,7 +61,6 @@ module.exports = function(core) {
60
61
  return core.assess.dataflow.propagation.urlInstrumentation.searchParams = {
61
62
  install() {
62
63
  depHooks.resolve({ name: 'url' }, (url) => {
63
-
64
64
  const name = 'url.URLSearchParams';
65
65
 
66
66
  patcher.patch(url, 'URLSearchParams', {
@@ -68,7 +68,7 @@ module.exports = function(core) {
68
68
  patchType,
69
69
  post(data) {
70
70
  const { args, obj, result } = data;
71
- if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
71
+ if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return;
72
72
 
73
73
  const [params] = args;
74
74
 
@@ -40,14 +40,14 @@ describe('assess dataflow propagation url.URLSearchParams', function () {
40
40
  });
41
41
  });
42
42
 
43
- it('will not propagate if there is no assess context', function () {
43
+ it('will not propagate if there is no assess policy in request context', function () {
44
44
  simulateRequestScope(function () {
45
45
  const value = trackString('foo');
46
46
  const result = new url.URLSearchParams('?query='.concat(value));
47
47
  const input = result.get('query');
48
48
  expect(input).to.be.equal('foo');
49
49
  expect(tracker.getData(input)).to.be.null;
50
- }, {});
50
+ }, { assess: { policy: null } });
51
51
  });
52
52
 
53
53
  it('will not propagate if instrumentation is locked', function () {
@@ -15,14 +15,17 @@
15
15
 
16
16
  'use strict';
17
17
 
18
+ const { InstrumentationType: { PROPAGATOR } } = require('../../../../constants');
18
19
  const { patchType } = require('../../common');
19
20
 
21
+ const { primordials: { StringPrototypeSplit } } = require('@contrast/common');
22
+
20
23
  module.exports = function(core) {
21
24
  const {
22
- scopes: { sources, instrumentation },
23
25
  patcher,
24
26
  depHooks,
25
27
  assess: {
28
+ getSourceContext,
26
29
  inspect, // todo: remove
27
30
  eventFactory: { createPropagationEvent },
28
31
  dataflow: { tracker }
@@ -91,7 +94,7 @@ module.exports = function(core) {
91
94
  patchType,
92
95
  post(data) {
93
96
  const { args, result } = data;
94
- if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
97
+ if (!result || !args[0] || !getSourceContext(PROPAGATOR)) return;
95
98
 
96
99
  const [input, basename] = args;
97
100
  let url = input;
@@ -143,7 +146,7 @@ module.exports = function(core) {
143
146
  if (part !== 'null') {
144
147
 
145
148
  if (key === 'origin') {
146
- const [protocol, originWithoutProtocol] = part.split(new RegExp('(?<=//)'));
149
+ const [protocol, originWithoutProtocol] = StringPrototypeSplit.call(part, new RegExp('(?<=//)'));
147
150
  const idx1 = href.indexOf(protocol);
148
151
  const idx2 = href.indexOf(originWithoutProtocol, idx - 1);
149
152
  substr = href.substring(idx1, idx1 + protocol.length).concat(href.substring(idx2, idx2 + originWithoutProtocol.length));
@@ -67,14 +67,14 @@ describe('assess dataflow propagation url.URL', function () {
67
67
  });
68
68
  });
69
69
 
70
- it('will not propagate if there is no assess context', function () {
70
+ it('will not propagate if there is no assess policy in request context', function () {
71
71
  simulateRequestScope(function () {
72
72
  const value = trackString('foo');
73
73
  const result = new url.URL('http://'.concat(value, ':3000/path'));
74
74
  keys.forEach((key) => {
75
75
  expect(tracker.getData(result[key])).to.be.null;
76
76
  });
77
- }, {});
77
+ }, { assess: { policy: null } });
78
78
  });
79
79
 
80
80
  it('will not propagate if there instrumentation is locked', function () {
@@ -15,16 +15,17 @@
15
15
 
16
16
  'use strict';
17
17
 
18
- const { patchType } = require('../common');
19
- const { isString } = require('@contrast/common');
18
+ const { isString, primordials: { StringPrototypeMatch, StringPrototypeToLowerCase } } = require('@contrast/common');
19
+ const { InstrumentationType: { PROPAGATOR } } = require('../../../constants');
20
20
  const { createAppendTags } = require('../../tag-utils');
21
+ const { patchType } = require('../common');
21
22
 
22
23
  module.exports = function(core) {
23
24
  const {
24
- scopes: { sources, instrumentation },
25
25
  patcher,
26
26
  depHooks,
27
27
  assess: {
28
+ getSourceContext,
28
29
  eventFactory: { createPropagationEvent },
29
30
  dataflow: { tracker }
30
31
  }
@@ -40,13 +41,13 @@ module.exports = function(core) {
40
41
  patchType,
41
42
  post(data) {
42
43
  const { args, result, hooked, orig } = data;
43
- if (!result || !args[0] || !isString(args[0]) || !sources.getStore()?.assess || instrumentation.isLocked()) return;
44
+ if (!result || !args[0] || !isString(args[0]) || !getSourceContext(PROPAGATOR)) return;
44
45
 
45
46
  let idx = 0;
46
47
  let newTags = {};
47
48
  const history = [];
48
49
  const eventArgs = [];
49
- const formatChars = args[0].includes('%') ? args[0].match(/[^%]+/g).map((x) => x[0]) : [];
50
+ const formatChars = args[0].includes('%') ? StringPrototypeMatch.call(args[0], /[^%]+/g).map((x) => x[0]) : [];
50
51
  let i = 0;
51
52
 
52
53
  if (formatChars.length > 0) {
@@ -61,7 +62,7 @@ module.exports = function(core) {
61
62
 
62
63
  if (formatChar === 'j') {
63
64
  arg = JSON.stringify(arg);
64
- } else if (formatChar.toLowerCase() === 'o') {
65
+ } else if (StringPrototypeToLowerCase.call(formatChar) === 'o') {
65
66
  // TO-DO: NODE-3235
66
67
  }
67
68
  }
@@ -25,12 +25,12 @@ describe('assess dataflow propagation util.format', function () {
25
25
  core.depHooks.resolve.yield(util);
26
26
  });
27
27
 
28
- it('will not propagate if there is no assess context', function () {
28
+ it('will not propagate if there is no assess policy in request context', function () {
29
29
  simulateRequestScope(function () {
30
30
  const value = trackString('foo');
31
31
  const result = util.format('%s:%s', value, 'bar');
32
32
  expect(tracker.getData(result)).to.be.null;
33
- }, {});
33
+ }, { assess: { policy: null } });
34
34
  });
35
35
 
36
36
  it('will not propagate if there instrumentation is locked', function () {
@@ -26,6 +26,7 @@ module.exports = function (core) {
26
26
  depHooks,
27
27
  patcher,
28
28
  assess: {
29
+ getSourceContext,
29
30
  eventFactory: { createPropagationEvent },
30
31
  dataflow: { tracker }
31
32
  }
@@ -73,7 +74,8 @@ module.exports = function (core) {
73
74
  const matches = validator === 'matches';
74
75
  if (
75
76
  data.result &&
76
- (!matches || (matches && core.config.assess.trust_custom_validators))
77
+ (!matches || (matches && core.config.assess.trust_custom_validators)) &&
78
+ getSourceContext()
77
79
  ) {
78
80
  const trackingData = tracker.getData(data.args[0]);
79
81
  if (trackingData) {
@@ -104,7 +106,7 @@ module.exports = function (core) {
104
106
  name: `validator.${untracker}`,
105
107
  patchType,
106
108
  post(data) {
107
- if (data.result) {
109
+ if (data.result && getSourceContext()) {
108
110
  const trackingData = tracker.getData(data.args[0]);
109
111
  if (trackingData) {
110
112
  tracker.untrack(data.args[0]);
@@ -121,6 +123,7 @@ module.exports = function (core) {
121
123
  name: `validator.${sanitizer}`,
122
124
  patchType,
123
125
  post(data) {
126
+ if (!getSourceContext()) return;
124
127
  const trackingData = tracker.getData(data.args[0]);
125
128
  if (trackingData) {
126
129
  const newTags = {};
@@ -153,6 +156,8 @@ module.exports = function (core) {
153
156
  name: `validator.${method}`,
154
157
  patchType,
155
158
  post(data) {
159
+ if (!getSourceContext()) return;
160
+
156
161
  const options = data.args[1];
157
162
  const trackingData = tracker.getData(data.args[0]);
158
163
 
@@ -16,7 +16,7 @@
16
16
  'use strict';
17
17
  const {
18
18
  DataflowTag: { UNTRUSTED },
19
- ArrayPrototypeJoin,
19
+ primordials: { ArrayPrototypeJoin },
20
20
  Rule: { CMD_INJECTION: ruleId },
21
21
  isString,
22
22
  } = require('@contrast/common');
@@ -6,7 +6,7 @@ const {
6
6
  const sinon = require('sinon');
7
7
  const { expect } = require('chai');
8
8
  const { initAssessFixture } = require('@contrast/test/fixtures');
9
- const { UtilInspect } = require('@contrast/common');
9
+ const { primordials: { UtilInspect } } = require('@contrast/common');
10
10
 
11
11
  describe('assess dataflow sinks child_process', function () {
12
12
  let core, child_process, simulateRequestScope, trackString, tracker, reportFindings;
@@ -26,7 +26,7 @@ const {
26
26
  FS_METHODS,
27
27
  Rule: { PATH_TRAVERSAL: ruleId },
28
28
  isString,
29
- ArrayPrototypeJoin,
29
+ primordials: { ArrayPrototypeJoin },
30
30
  } = require('@contrast/common');
31
31
  const { InstrumentationType: { RULE } } = require('../../../constants');
32
32
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  const sinon = require('sinon');
4
4
  const { expect } = require('chai');
5
- const { FS_METHODS, ArrayPrototypeJoin, UtilInspect } = require('@contrast/common');
5
+ const { FS_METHODS, primordials: { ArrayPrototypeJoin, UtilInspect } } = require('@contrast/common');
6
6
  const { initAssessFixture } = require('@contrast/test/fixtures');
7
7
 
8
8
  describe('assess dataflow sinks path-traversal', function () {
@@ -17,7 +17,7 @@
17
17
 
18
18
  const {
19
19
  isString,
20
- ArrayPrototypeJoin,
20
+ primordials: { ArrayPrototypeJoin },
21
21
  DataflowTag: {
22
22
  UNTRUSTED,
23
23
  CUSTOM_ENCODED_TRUST_BOUNDARY_VIOLATION,
@@ -27,6 +27,7 @@ const {
27
27
  LIMITED_CHARS
28
28
  },
29
29
  Rule: { SSRF: ruleId },
30
+ primordials: { RegExpPrototypeExec }
30
31
  } = require('@contrast/common');
31
32
  const { InstrumentationType: { RULE } } = require('../../../../constants');
32
33
  const { createAppendTags } = require('../../../tag-utils');
@@ -84,7 +85,7 @@ module.exports = function(core) {
84
85
  function containsTrustedLib(stack) {
85
86
  for (const { file } of stack) {
86
87
  for (const trusted of trustedLibs) {
87
- if (trusted.exec(file)) {
88
+ if (RegExpPrototypeExec.call(trusted, file)) {
88
89
  return true;
89
90
  }
90
91
  }
@@ -7,7 +7,7 @@ const {
7
7
  UNTRUSTED,
8
8
  LIMITED_CHARS
9
9
  },
10
- UtilInspect
10
+ primordials: { UtilInspect }
11
11
  } = require('@contrast/common');
12
12
 
13
13
  const { initAssessFixture } = require('@contrast/test/fixtures');
@@ -73,17 +73,15 @@ describe('assess dataflow sinks http, http2, spdy', function () {
73
73
  });
74
74
 
75
75
  it('skips instrumentation if the content-type is safe', function () {
76
- const store = {
77
- assess: { responseData: { contentType: 'application/json' } },
78
- };
79
-
80
76
  simulateRequestScope(function () {
77
+ core.scopes.sources.getStore().assess.responseData.contentType = 'application/json';
78
+
81
79
  const str = trackString('hello world');
82
80
  const { extern } = tracker.getData(str);
83
81
 
84
82
  response[method](extern);
85
83
  expect(reportFindings).to.not.have.been.called;
86
- }, store);
84
+ });
87
85
  });
88
86
 
89
87
  it('skips instrumentation if the string is safe', function () {
@@ -26,7 +26,7 @@ const {
26
26
  URL_ENCODED,
27
27
  },
28
28
  isString,
29
- ArrayPrototypeJoin,
29
+ primordials: { ArrayPrototypeJoin },
30
30
  } = require('@contrast/common');
31
31
  const { InstrumentationType: { RULE } } = require('../../../constants');
32
32
  const { createAppendTags } = require('../../tag-utils');
@@ -27,8 +27,10 @@ const {
27
27
  Rule: { UNSAFE_CODE_EXECUTION: ruleId },
28
28
  isNonEmptyObject,
29
29
  isString,
30
- ArrayPrototypeJoin,
31
- StringPrototypeSplit,
30
+ primordials: {
31
+ ArrayPrototypeJoin,
32
+ StringPrototypeSplit,
33
+ },
32
34
  traverseValues,
33
35
  } = require('@contrast/common');
34
36
  const { InstrumentationType: { RULE } } = require('../../../constants');