@contrast/assess 1.31.0 → 1.32.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 (154) hide show
  1. package/lib/crypto-analysis/install/crypto.test.js +146 -0
  2. package/lib/crypto-analysis/install/math.test.js +65 -0
  3. package/lib/dataflow/index.test.js +36 -0
  4. package/lib/dataflow/propagation/index.test.js +103 -0
  5. package/lib/dataflow/propagation/install/JSON/index.test.js +50 -0
  6. package/lib/dataflow/propagation/install/JSON/parse-fn.test.js +232 -0
  7. package/lib/dataflow/propagation/install/JSON/parse.test.js +968 -0
  8. package/lib/dataflow/propagation/install/JSON/stringify.test.js +265 -0
  9. package/lib/dataflow/propagation/install/array-prototype-join.test.js +106 -0
  10. package/lib/dataflow/propagation/install/buffer.test.js +109 -0
  11. package/lib/dataflow/propagation/install/contrast-methods/add.test.js +94 -0
  12. package/lib/dataflow/propagation/install/contrast-methods/index.test.js +49 -0
  13. package/lib/dataflow/propagation/install/contrast-methods/number.test.js +50 -0
  14. package/lib/dataflow/propagation/install/contrast-methods/string.test.js +148 -0
  15. package/lib/dataflow/propagation/install/contrast-methods/tag.test.js +145 -0
  16. package/lib/dataflow/propagation/install/decode-uri-component.test.js +78 -0
  17. package/lib/dataflow/propagation/install/ejs/escape-xml.test.js +69 -0
  18. package/lib/dataflow/propagation/install/ejs/template.test.js +62 -0
  19. package/lib/dataflow/propagation/install/encode-uri.test.js +83 -0
  20. package/lib/dataflow/propagation/install/escape-html.test.js +71 -0
  21. package/lib/dataflow/propagation/install/escape.test.js +73 -0
  22. package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.test.js +71 -0
  23. package/lib/dataflow/propagation/install/isnumeric-0.test.js +58 -0
  24. package/lib/dataflow/propagation/install/joi/any.test.js +270 -0
  25. package/lib/dataflow/propagation/install/joi/array.test.js +912 -0
  26. package/lib/dataflow/propagation/install/joi/boolean.test.js +103 -0
  27. package/lib/dataflow/propagation/install/joi/expression.test.js +76 -0
  28. package/lib/dataflow/propagation/install/joi/index.test.js +39 -0
  29. package/lib/dataflow/propagation/install/joi/number.test.js +103 -0
  30. package/lib/dataflow/propagation/install/joi/object.test.js +119 -0
  31. package/lib/dataflow/propagation/install/joi/ref.test.js +607 -0
  32. package/lib/dataflow/propagation/install/joi/string-schema.test.js +513 -0
  33. package/lib/dataflow/propagation/install/mongoose/index.test.js +42 -0
  34. package/lib/dataflow/propagation/install/mongoose/schema-map.test.js +348 -0
  35. package/lib/dataflow/propagation/install/mongoose/schema-mixed.test.js +512 -0
  36. package/lib/dataflow/propagation/install/mongoose/schema-string.test.js +160 -0
  37. package/lib/dataflow/propagation/install/mustache-escape.test.js +62 -0
  38. package/lib/dataflow/propagation/install/mysql-connection-escape.test.js +74 -0
  39. package/lib/dataflow/propagation/install/parse-int.test.js +48 -0
  40. package/lib/dataflow/propagation/install/path/basename.test.js +143 -0
  41. package/lib/dataflow/propagation/install/path/dirname.test.js +167 -0
  42. package/lib/dataflow/propagation/install/path/extname.test.js +141 -0
  43. package/lib/dataflow/propagation/install/path/format.test.js +250 -0
  44. package/lib/dataflow/propagation/install/path/index.test.js +45 -0
  45. package/lib/dataflow/propagation/install/path/join-and-resolve.test.js +485 -0
  46. package/lib/dataflow/propagation/install/path/normalize.test.js +176 -0
  47. package/lib/dataflow/propagation/install/path/parse.test.js +238 -0
  48. package/lib/dataflow/propagation/install/path/relative.test.js +239 -0
  49. package/lib/dataflow/propagation/install/path/toNamespacedPath.test.js +158 -0
  50. package/lib/dataflow/propagation/install/pug/index.test.js +55 -0
  51. package/lib/dataflow/propagation/install/pug-runtime-escape.test.js +69 -0
  52. package/lib/dataflow/propagation/install/querystring/escape.test.js +63 -0
  53. package/lib/dataflow/propagation/install/querystring/index.test.js +40 -0
  54. package/lib/dataflow/propagation/install/querystring/parse.test.js +272 -0
  55. package/lib/dataflow/propagation/install/querystring/stringify.test.js +301 -0
  56. package/lib/dataflow/propagation/install/reg-exp-prototype-exec.test.js +281 -0
  57. package/lib/dataflow/propagation/install/send.test.js +63 -0
  58. package/lib/dataflow/propagation/install/sequelize/query-generator.test.js +73 -0
  59. package/lib/dataflow/propagation/install/sequelize/sql-string.test.js +130 -0
  60. package/lib/dataflow/propagation/install/sql-template-strings.test.js +100 -0
  61. package/lib/dataflow/propagation/install/string/concat.test.js +132 -0
  62. package/lib/dataflow/propagation/install/string/format-methods.test.js +61 -0
  63. package/lib/dataflow/propagation/install/string/html-methods.test.js +164 -0
  64. package/lib/dataflow/propagation/install/string/index.test.js +103 -0
  65. package/lib/dataflow/propagation/install/string/match-all.test.js +399 -0
  66. package/lib/dataflow/propagation/install/string/match.test.js +361 -0
  67. package/lib/dataflow/propagation/install/string/replace.test.js +588 -0
  68. package/lib/dataflow/propagation/install/string/slice.test.js +265 -0
  69. package/lib/dataflow/propagation/install/string/split.test.js +500 -0
  70. package/lib/dataflow/propagation/install/string/substring.test.js +238 -0
  71. package/lib/dataflow/propagation/install/string/trim.test.js +122 -0
  72. package/lib/dataflow/propagation/install/unescape.test.js +78 -0
  73. package/lib/dataflow/propagation/install/url/domain-parsers.test.js +63 -0
  74. package/lib/dataflow/propagation/install/url/parse.test.js +391 -0
  75. package/lib/dataflow/propagation/install/url/searchParams.test.js +538 -0
  76. package/lib/dataflow/propagation/install/url/url.test.js +466 -0
  77. package/lib/dataflow/propagation/install/util-format.test.js +336 -0
  78. package/lib/dataflow/propagation/install/validator/hooks.test.js +211 -0
  79. package/lib/dataflow/sinks/index.test.js +78 -0
  80. package/lib/dataflow/sinks/install/child-process.test.js +338 -0
  81. package/lib/dataflow/sinks/install/eval.test.js +95 -0
  82. package/lib/dataflow/sinks/install/express/index.test.js +33 -0
  83. package/lib/dataflow/sinks/install/express/reflected-xss.js +55 -57
  84. package/lib/dataflow/sinks/install/express/reflected-xss.test.js +109 -0
  85. package/lib/dataflow/sinks/install/express/unvalidated-redirect.test.js +144 -0
  86. package/lib/dataflow/sinks/install/fastify/index.test.js +32 -0
  87. package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.test.js +130 -0
  88. package/lib/dataflow/sinks/install/fs.test.js +138 -0
  89. package/lib/dataflow/sinks/install/function.test.js +103 -0
  90. package/lib/dataflow/sinks/install/hapi/index.test.js +32 -0
  91. package/lib/dataflow/sinks/install/hapi/unvalidated-redirect.test.js +130 -0
  92. package/lib/dataflow/sinks/install/http/index.test.js +33 -0
  93. package/lib/dataflow/sinks/install/http/request.test.js +184 -0
  94. package/lib/dataflow/sinks/install/http/server-response.test.js +162 -0
  95. package/lib/dataflow/sinks/install/koa/index.test.js +32 -0
  96. package/lib/dataflow/sinks/install/koa/unvalidated-redirect.test.js +200 -0
  97. package/lib/dataflow/sinks/install/libxmljs.test.js +158 -0
  98. package/lib/dataflow/sinks/install/marsdb.test.js +166 -0
  99. package/lib/dataflow/sinks/install/mongodb.test.js +621 -0
  100. package/lib/dataflow/sinks/install/mssql.test.js +136 -0
  101. package/lib/dataflow/sinks/install/mysql.test.js +233 -0
  102. package/lib/dataflow/sinks/install/node-serialize.test.js +85 -0
  103. package/lib/dataflow/sinks/install/postgres.test.js +158 -0
  104. package/lib/dataflow/sinks/install/restify.test.js +142 -0
  105. package/lib/dataflow/sinks/install/sequelize.test.js +100 -0
  106. package/lib/dataflow/sinks/install/sqlite3.test.js +118 -0
  107. package/lib/dataflow/sinks/install/vm.test.js +326 -0
  108. package/lib/dataflow/sources/handler.test.js +463 -0
  109. package/lib/dataflow/sources/index.test.js +58 -0
  110. package/lib/dataflow/sources/install/body-parser1.test.js +248 -0
  111. package/lib/dataflow/sources/install/busboy.test.js +152 -0
  112. package/lib/dataflow/sources/install/cookie-parser1.test.js +143 -0
  113. package/lib/dataflow/sources/install/express/params.test.js +105 -0
  114. package/lib/dataflow/sources/install/express/parsedUrl.test.js +65 -0
  115. package/lib/dataflow/sources/install/fastify/fastify.test.js +210 -0
  116. package/lib/dataflow/sources/install/fastify/index.test.js +33 -0
  117. package/lib/dataflow/sources/install/formidable1.test.js +119 -0
  118. package/lib/dataflow/sources/install/hapi/hapi.test.js +172 -0
  119. package/lib/dataflow/sources/install/hapi/index.test.js +33 -0
  120. package/lib/dataflow/sources/install/http.test.js +155 -0
  121. package/lib/dataflow/sources/install/koa/index.test.js +40 -0
  122. package/lib/dataflow/sources/install/koa/koa-bodyparsers.test.js +161 -0
  123. package/lib/dataflow/sources/install/koa/koa-multer.test.js +197 -0
  124. package/lib/dataflow/sources/install/koa/koa-routers.test.js +146 -0
  125. package/lib/dataflow/sources/install/koa/koa2.test.js +145 -0
  126. package/lib/dataflow/sources/install/multer1.test.js +145 -0
  127. package/lib/dataflow/sources/install/qs6.test.js +131 -0
  128. package/lib/dataflow/sources/install/querystring.test.js +82 -0
  129. package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.test.js +88 -0
  130. package/lib/dataflow/sources/install/restify/index.test.js +38 -0
  131. package/lib/dataflow/sources/install/restify/jsonBodyParser.test.js +144 -0
  132. package/lib/dataflow/sources/install/restify/router.test.js +83 -0
  133. package/lib/dataflow/tag-utils-complete.test.js +27 -0
  134. package/lib/dataflow/tag-utils.test.js +192 -0
  135. package/lib/dataflow/tracker.test.js +216 -0
  136. package/lib/dataflow/utils/is-safe-content-type.test.js +16 -0
  137. package/lib/dataflow/utils/is-vulnerable.test.js +115 -0
  138. package/lib/event-factory.test.js +321 -0
  139. package/lib/get-policy.test.js +194 -0
  140. package/lib/get-source-context.test.js +108 -0
  141. package/lib/index.test.js +41 -0
  142. package/lib/make-source-context.test.js +50 -0
  143. package/lib/response-scanning/handlers/index.test.js +425 -0
  144. package/lib/response-scanning/handlers/utils.test.js +391 -0
  145. package/lib/response-scanning/index.test.js +41 -0
  146. package/lib/response-scanning/install/http.test.js +175 -0
  147. package/lib/rule-scopes.test.js +27 -0
  148. package/lib/session-configuration/handlers.test.js +84 -0
  149. package/lib/session-configuration/index.test.js +36 -0
  150. package/lib/session-configuration/install/express-session.test.js +220 -0
  151. package/lib/session-configuration/install/fastify-cookie.test.js +65 -0
  152. package/lib/session-configuration/install/hapi.test.js +269 -0
  153. package/lib/session-configuration/install/koa.test.js +92 -0
  154. package/package.json +2 -2
@@ -0,0 +1,73 @@
1
+
2
+ 'use strict';
3
+
4
+ const { expect } = require('chai');
5
+ const sinon = require('sinon');
6
+ const {
7
+ DataflowTag: { UNTRUSTED, WEAK_URL_ENCODED }
8
+ } = require('@contrast/common');
9
+ const { initAssessFixture } = require('@contrast/test/fixtures');
10
+
11
+ describe('assess dataflow propagation escape', function () {
12
+ let core, trackString, simulateRequestScope, tracker;
13
+
14
+ beforeEach(function () {
15
+ ({
16
+ core,
17
+ simulateRequestScope,
18
+ trackString
19
+ } = initAssessFixture());
20
+
21
+ tracker = core.assess.dataflow.tracker;
22
+ core.assess.dataflow.propagation.escape.install();
23
+ });
24
+
25
+ afterEach(function () {
26
+ core.assess.dataflow.propagation.escape.uninstall();
27
+ sinon.resetHistory();
28
+ });
29
+
30
+ [
31
+ {
32
+ str: '?test=str',
33
+ tags: {
34
+ [UNTRUSTED]: [0, 8],
35
+ },
36
+ expected: {
37
+ [UNTRUSTED]: [0, 12],
38
+ [WEAK_URL_ENCODED]: [0, 12],
39
+ }
40
+ },
41
+ {
42
+ str: 'not-tracked',
43
+ }
44
+ ].forEach(({ str, tags, expected }) => {
45
+ it('propagates correctly', function () {
46
+ simulateRequestScope(function () {
47
+ const value = tags ? trackString(str, { tags }) : str;
48
+
49
+ const result = escape(value);
50
+ const strInfo = tracker.getData(result);
51
+ expect(strInfo?.tags).to.deep.equal(expected);
52
+ });
53
+ });
54
+ });
55
+
56
+ it('will not propagate if there is no assess context', function () {
57
+ simulateRequestScope(function () {
58
+ const value = trackString('?test=str');
59
+ const result = escape(value);
60
+ expect(tracker.getData(result)).to.be.null;
61
+ }, {});
62
+ });
63
+
64
+ it('will not propagate if there instrumentation is locked', function () {
65
+ simulateRequestScope(function () {
66
+ core.scopes.instrumentation.run({ lock: true }, function () {
67
+ const value = trackString('?test=str');
68
+ const result = escape(value);
69
+ expect(tracker.getData(result)).to.be.null;
70
+ });
71
+ });
72
+ });
73
+ });
@@ -0,0 +1,71 @@
1
+ 'use strict';
2
+
3
+ const {
4
+ DataflowTag: { UNTRUSTED, HTML_ENCODED }
5
+ } = require('@contrast/common');
6
+ const { expect } = require('chai');
7
+ const sinon = require('sinon');
8
+ const { initAssessFixture } = require('@contrast/test/fixtures');
9
+
10
+ describe('assess dataflow propagation handlebars.Utils.escapeExpression', function () {
11
+ let core, trackString, simulateRequestScope, tracker, mockHandlebars;
12
+
13
+ beforeEach(function () {
14
+ ({
15
+ core,
16
+ simulateRequestScope,
17
+ trackString
18
+ } = initAssessFixture());
19
+
20
+ mockHandlebars = {
21
+ Utils: {
22
+ escapeExpression: (str) => `mock-escape_${str}_mock-escape`
23
+ }
24
+ };
25
+
26
+ tracker = core.assess.dataflow.tracker;
27
+ core.assess.dataflow.propagation.handlebarsEscapeExpression.install();
28
+ core.depHooks.resolve.yield(mockHandlebars);
29
+ });
30
+
31
+ afterEach(function () {
32
+ sinon.resetHistory();
33
+ });
34
+
35
+ it('propagates correctly', function () {
36
+ simulateRequestScope(function () {
37
+ const notTrackedValue = 'foo';
38
+ const trackedValue = trackString('foo');
39
+
40
+ const notTrackedResult = mockHandlebars.Utils.escapeExpression(notTrackedValue);
41
+ const notTrackedStrInfo = tracker.getData(notTrackedResult);
42
+
43
+ const trackedResult = mockHandlebars.Utils.escapeExpression(trackedValue);
44
+ const trackedStrInfo = tracker.getData(trackedResult);
45
+
46
+ expect(notTrackedStrInfo).to.be.null;
47
+ expect(trackedStrInfo?.tags).to.deep.equal({
48
+ [UNTRUSTED]: [0, trackedStrInfo.value.length - 1],
49
+ [HTML_ENCODED]: [0, trackedStrInfo.value.length - 1]
50
+ });
51
+ });
52
+ });
53
+
54
+ it('will not propagate if there is no assess context', function () {
55
+ simulateRequestScope(function () {
56
+ const value = trackString('foo');
57
+ const result = mockHandlebars.Utils.escapeExpression(value);
58
+ expect(tracker.getData(result)).to.be.null;
59
+ }, {});
60
+ });
61
+
62
+ it('will not propagate if there instrumentation is locked', function () {
63
+ simulateRequestScope(function () {
64
+ core.scopes.instrumentation.run({ lock: true }, function () {
65
+ const value = trackString('foo');
66
+ const result = mockHandlebars.Utils.escapeExpression(value);
67
+ expect(tracker.getData(result)).to.be.null;
68
+ });
69
+ });
70
+ });
71
+ });
@@ -0,0 +1,58 @@
1
+ 'use strict';
2
+
3
+ const { expect } = require('chai');
4
+ const { initAssessFixture } = require('@contrast/test/fixtures');
5
+
6
+ describe('assess dataflow propagation isnumeric', function () {
7
+ let core, trackString, simulateRequestScope, tracker, mockIsNumeric, isNumeric, result;
8
+
9
+ beforeEach(function () {
10
+ ({
11
+ core,
12
+ simulateRequestScope,
13
+ trackString
14
+ } = initAssessFixture());
15
+
16
+ result = 1;
17
+ mockIsNumeric = function (value) {
18
+ return result;
19
+ };
20
+ tracker = core.assess.dataflow.tracker;
21
+ core.depHooks.resolve.callsFake(function (_e, cb) {
22
+ isNumeric = cb(mockIsNumeric, { version: '0.3.3' });
23
+ });
24
+ core.assess.dataflow.propagation.isnumericInstrumentation.install();
25
+ });
26
+
27
+ it('will not untrack when check returns falsey', function () {
28
+ simulateRequestScope(function () {
29
+ result = false;
30
+ const str = trackString('foo');
31
+ isNumeric(str);
32
+ expect(tracker.getData(str)).to.deep.include({
33
+ context: 'UNKNOWN.val',
34
+ name: 'assess-dataflow-fixture',
35
+ fieldName: 'val',
36
+ pathName: 'val',
37
+ stack: [],
38
+ inputType: 'UNKNOWN',
39
+ tags: { UNTRUSTED: [0, 2] },
40
+ result: { tracked: true, value: 'foo' },
41
+ });
42
+ });
43
+ });
44
+
45
+ it('untracks when check returns truthy', function () {
46
+ simulateRequestScope(function () {
47
+ result = true;
48
+ const str = trackString('30000');
49
+ isNumeric(str);
50
+ expect(tracker.getData(str)).to.be.null;
51
+ expect(core.logger.trace).to.have.been.calledWithMatch({
52
+ funcKey: 'assess-dataflow-propagator:isnumeric',
53
+ sanitizer: 'isnumeric@0.3.3',
54
+ value: '30000',
55
+ }, 'untracked a string value');
56
+ });
57
+ });
58
+ });
@@ -0,0 +1,270 @@
1
+ 'use strict';
2
+
3
+ const { expect } = require('chai');
4
+ const { initAssessFixture } = require('@contrast/test/fixtures');
5
+ const { DataflowTag } = require('@contrast/common');
6
+
7
+ describe('assess dataflow propagation joi object validator with custom or extern fn', function() {
8
+ let core, joi, tracker, trackString, simulateRequestScope;
9
+
10
+ beforeEach(function() {
11
+ ({ core, simulateRequestScope, trackString } = initAssessFixture());
12
+ tracker = core.assess.dataflow.tracker;
13
+ core.config.assess.trust_custom_validators = true;
14
+
15
+ core.depHooks.resolve.withArgs({ name: 'joi', file: 'lib/types/any', version: '>=17.0.0' }).yields(require('joi-17/lib/types/any'));
16
+
17
+ require('./index')(core).install();
18
+ joi = require('joi-17');
19
+ });
20
+
21
+ afterEach(function() {
22
+ Object.keys(require.cache).forEach((key) => {
23
+ if (key.includes('joi')) {
24
+ delete require.cache[key];
25
+ }
26
+ });
27
+ });
28
+
29
+ it(`tracked values passing validation with a custom validator will be tagged with ${DataflowTag.CUSTOM_VALIDATED}`, function() {
30
+ simulateRequestScope(() => {
31
+ const tracked = trackString('test');
32
+ const schema = joi.custom((value, helper) => {
33
+ if (value === 'test') {
34
+ return value;
35
+ }
36
+
37
+ return helper.message('Invalid value');
38
+ });
39
+
40
+ const validated = schema.validate(tracked);
41
+ const data = tracker.getData(validated.value);
42
+
43
+ expect(tracked).to.equal(validated.value);
44
+ expect(validated.error).to.be.undefined;
45
+ expect(data.tags).to.deep.equal({
46
+ [DataflowTag.UNTRUSTED]: [0, 3],
47
+ [DataflowTag.CUSTOM_VALIDATED]: [0, 3],
48
+ });
49
+
50
+ expect(data.moduleName).to.equal('joi');
51
+ expect(data.methodName).to.equal('any.custom.validate');
52
+ });
53
+ });
54
+
55
+ it(`tracked values passing validation with a custom validator will be tagged with ${DataflowTag.CUSTOM_VALIDATED}`, function() {
56
+ simulateRequestScope(() => {
57
+ const tracked = trackString('test');
58
+ const schema = joi.custom((value, helper) => {
59
+ if (value.a === 'test' && value.b === 'test') {
60
+ return value;
61
+ }
62
+
63
+ return helper.message('Invalid value');
64
+ });
65
+
66
+ const validated = schema.validate({
67
+ a: tracked,
68
+ b: tracked
69
+ });
70
+
71
+ expect(validated.error).to.be.undefined;
72
+ Object.values(validated.value).forEach((v) => {
73
+ const data = tracker.getData(v);
74
+
75
+ expect(data.tags).to.deep.equal({
76
+ [DataflowTag.UNTRUSTED]: [0, 3],
77
+ [DataflowTag.CUSTOM_VALIDATED]: [0, 3],
78
+ });
79
+
80
+ expect(data.moduleName).to.equal('joi');
81
+ expect(data.methodName).to.equal('any.custom.validate');
82
+ });
83
+ });
84
+ });
85
+
86
+ it(`objects with tracked values passing validation with an external validator will be tagged with ${DataflowTag.CUSTOM_VALIDATED}`, function(done) {
87
+ simulateRequestScope(() => {
88
+ const tracked = trackString('test');
89
+ const schema = joi.any().external((value, helper) => {
90
+ if (value === 'test') {
91
+ return value;
92
+ }
93
+
94
+ return helper.message('Invalid value');
95
+ });
96
+
97
+ schema.validateAsync(tracked)
98
+ .then((validated) => {
99
+
100
+ const data = tracker.getData(validated);
101
+
102
+ expect(data.tags).to.deep.equal({
103
+ [DataflowTag.UNTRUSTED]: [0, 3],
104
+ [DataflowTag.CUSTOM_VALIDATED]: [0, 3],
105
+ });
106
+
107
+ expect(data.moduleName).to.equal('joi');
108
+ expect(data.methodName).to.equal('any.external');
109
+ done();
110
+ })
111
+ .catch(err => done(err));
112
+ });
113
+ });
114
+
115
+ it(`objects with tracked values passing validation with an external validator will be tagged with ${DataflowTag.CUSTOM_VALIDATED}`, function(done) {
116
+ simulateRequestScope(() => {
117
+ const tracked = trackString('test');
118
+ const schema = joi.any().external((value, helper) => {
119
+ if (value.a === 'test' && value.b === 'test') {
120
+ return value;
121
+ }
122
+
123
+ return helper.message('Invalid value');
124
+ });
125
+
126
+ schema.validateAsync({
127
+ a: tracked,
128
+ b: tracked
129
+ })
130
+ .then((validated) => {
131
+
132
+ Object.values(validated).forEach((v) => {
133
+ const data = tracker.getData(v);
134
+
135
+ expect(data.tags).to.deep.equal({
136
+ [DataflowTag.UNTRUSTED]: [0, 3],
137
+ [DataflowTag.CUSTOM_VALIDATED]: [0, 3],
138
+ });
139
+
140
+ expect(data.moduleName).to.equal('joi');
141
+ expect(data.methodName).to.equal('any.external');
142
+ });
143
+ done();
144
+ })
145
+ .catch(err => done(err));
146
+ });
147
+ });
148
+
149
+ it('tracked values not passing validation with a custom validator won\'t be tagged', function() {
150
+ simulateRequestScope(() => {
151
+ const tracked = trackString('value');
152
+ const schema = joi.object({
153
+ v1: joi.custom((value, helper) => {
154
+ if (value === 'test') {
155
+ return value;
156
+ }
157
+
158
+ return helper.message('Invalid value');
159
+ }),
160
+ v2: joi.custom((value) => {
161
+ if (value === 'test') {
162
+ return value;
163
+ }
164
+
165
+ throw new Error('Invalid value');
166
+ }),
167
+ v3: joi.custom((value) => {
168
+ if (value === 'test') {
169
+ return value;
170
+ }
171
+
172
+ return 'Invalid value';
173
+ }),
174
+ });
175
+
176
+
177
+ const validated = schema.validate({
178
+ v1: tracked,
179
+ v2: tracked,
180
+ v3: tracked
181
+ }, { abortEarly: false });
182
+
183
+ expect(validated.error).to.not.be.undefined;
184
+ Object.values(validated.value).forEach((v) => {
185
+ const data = tracker.getData(v);
186
+
187
+ if (data) {
188
+ expect(data.tags).to.deep.equal({
189
+ [DataflowTag.UNTRUSTED]: [0, 4],
190
+ });
191
+ expect(data.name).to.equal('assess-dataflow-fixture');
192
+ } else {
193
+ expect(data).to.be.null;
194
+ }
195
+ });
196
+ });
197
+ });
198
+
199
+ it('tracked values not passing validation with an external validator won\'t be tagged', function(done) {
200
+ simulateRequestScope(() => {
201
+ const tracked = trackString('value');
202
+ const schema = joi.object({
203
+ v1: joi.any().external((value, helper) => {
204
+ if (value === 'test') {
205
+ return value;
206
+ }
207
+
208
+ return helper.message('Invalid value');
209
+ }),
210
+ v2: joi.any().external((value) => {
211
+ if (value === 'test') {
212
+ return value;
213
+ }
214
+
215
+ throw new Error('Invalid value');
216
+ }),
217
+ v3: joi.any().external((value) => {
218
+ if (value === 'test') {
219
+ return value;
220
+ }
221
+
222
+ return 'Invalid value';
223
+ }),
224
+ });
225
+
226
+ const obj = {
227
+ v1: tracked,
228
+ v2: tracked,
229
+ v3: tracked,
230
+ };
231
+
232
+ schema.validateAsync(obj, { abortEarly: false })
233
+ .then(() => {
234
+ done('The validation should not pass');
235
+ })
236
+ .catch(() => {
237
+ Object.values(obj).forEach((v) => {
238
+ const data = tracker.getData(v);
239
+
240
+ expect(data.tags).to.deep.equal({
241
+ [DataflowTag.UNTRUSTED]: [0, 4],
242
+ });
243
+ expect(data.name).to.equal('assess-dataflow-fixture');
244
+ });
245
+ done();
246
+ })
247
+ .catch(err => done(err));
248
+
249
+ });
250
+ });
251
+
252
+ it('should not track the result of custom validation if the value is not tracked', function() {
253
+ simulateRequestScope(() => {
254
+ const schema = joi.custom((value, helper) => {
255
+ if (value === 'test') {
256
+ return value;
257
+ }
258
+
259
+ return helper.message('Invalid value');
260
+ });
261
+
262
+ const validated = schema.validate('test');
263
+ const data = tracker.getData(validated.value);
264
+
265
+ expect(data).to.be.null;
266
+ });
267
+ });
268
+ });
269
+
270
+