@contrast/assess 1.30.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 (156) 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.js +1 -1
  116. package/lib/dataflow/sources/install/fastify/fastify.test.js +210 -0
  117. package/lib/dataflow/sources/install/fastify/index.test.js +33 -0
  118. package/lib/dataflow/sources/install/formidable1.test.js +119 -0
  119. package/lib/dataflow/sources/install/hapi/hapi.test.js +172 -0
  120. package/lib/dataflow/sources/install/hapi/index.test.js +33 -0
  121. package/lib/dataflow/sources/install/http.test.js +155 -0
  122. package/lib/dataflow/sources/install/koa/index.test.js +40 -0
  123. package/lib/dataflow/sources/install/koa/koa-bodyparsers.test.js +161 -0
  124. package/lib/dataflow/sources/install/koa/koa-multer.test.js +197 -0
  125. package/lib/dataflow/sources/install/koa/koa-routers.test.js +146 -0
  126. package/lib/dataflow/sources/install/koa/koa2.test.js +145 -0
  127. package/lib/dataflow/sources/install/multer1.test.js +145 -0
  128. package/lib/dataflow/sources/install/qs6.test.js +131 -0
  129. package/lib/dataflow/sources/install/querystring.test.js +82 -0
  130. package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.test.js +88 -0
  131. package/lib/dataflow/sources/install/restify/index.test.js +38 -0
  132. package/lib/dataflow/sources/install/restify/jsonBodyParser.test.js +144 -0
  133. package/lib/dataflow/sources/install/restify/router.test.js +83 -0
  134. package/lib/dataflow/tag-utils-complete.test.js +27 -0
  135. package/lib/dataflow/tag-utils.test.js +192 -0
  136. package/lib/dataflow/tracker.test.js +216 -0
  137. package/lib/dataflow/utils/is-safe-content-type.test.js +16 -0
  138. package/lib/dataflow/utils/is-vulnerable.test.js +115 -0
  139. package/lib/event-factory.test.js +321 -0
  140. package/lib/get-policy.test.js +194 -0
  141. package/lib/get-source-context.test.js +108 -0
  142. package/lib/index.test.js +41 -0
  143. package/lib/make-source-context.test.js +50 -0
  144. package/lib/response-scanning/handlers/index.test.js +425 -0
  145. package/lib/response-scanning/handlers/utils.test.js +391 -0
  146. package/lib/response-scanning/index.test.js +41 -0
  147. package/lib/response-scanning/install/http.test.js +175 -0
  148. package/lib/rule-scopes.test.js +27 -0
  149. package/lib/session-configuration/handlers.test.js +84 -0
  150. package/lib/session-configuration/index.test.js +36 -0
  151. package/lib/session-configuration/install/express-session.test.js +220 -0
  152. package/lib/session-configuration/install/fastify-cookie.test.js +65 -0
  153. package/lib/session-configuration/install/hapi.test.js +269 -0
  154. package/lib/session-configuration/install/koa.js +50 -44
  155. package/lib/session-configuration/install/koa.test.js +92 -0
  156. package/package.json +2 -2
@@ -0,0 +1,238 @@
1
+ 'use strict';
2
+
3
+ const sinon = require('sinon');
4
+ const { expect } = require('chai');
5
+ const { initAssessFixture } = require('@contrast/test/fixtures');
6
+ const { DataflowTag: { UNTRUSTED } } = require('@contrast/common');
7
+
8
+ describe('assess dataflow propagation path parse', function () {
9
+ let core, tracker, createPropagationEvent, trackString, simulateRequestScope;
10
+
11
+ beforeEach(function () {
12
+ ({ core, simulateRequestScope, trackString } = initAssessFixture());
13
+ tracker = core.assess.dataflow.tracker;
14
+ createPropagationEvent = sinon.spy(
15
+ core.assess.eventFactory,
16
+ 'createPropagationEvent'
17
+ );
18
+ core.assess.dataflow.propagation.stringInstrumentation.concat.install();
19
+ });
20
+
21
+ ['posix', 'win32'].forEach((os) => {
22
+ describe(os, function () {
23
+ let path;
24
+
25
+ beforeEach(function () {
26
+ path = require('path')[os];
27
+
28
+ core.depHooks.resolve.yields(path);
29
+ const parseInstr = require('./parse')(core);
30
+ parseInstr.install();
31
+ });
32
+
33
+ it('should ignore empty string', function () {
34
+ simulateRequestScope(function () {
35
+ const result = path.parse('');
36
+ Object.keys(result).forEach((key) => {
37
+ const valInfo = tracker.getData(result[key]);
38
+ expect(valInfo).to.be.null;
39
+ });
40
+ });
41
+ });
42
+
43
+ it('will not propagate if there is no assess context', function () {
44
+ simulateRequestScope(function () {
45
+ const str = trackString('/path/to/file.txt');
46
+ const result = path.parse(str);
47
+ Object.keys(result).forEach((key) => {
48
+ const valInfo = tracker.getData(result[key]);
49
+ expect(valInfo).to.be.null;
50
+ });
51
+ }, {});
52
+ });
53
+
54
+ it('will not propagate if instrumentation is locked', function () {
55
+ simulateRequestScope(function () {
56
+ core.scopes.instrumentation.run({ lock: true }, function () {
57
+ const str = trackString('/path/to/file.txt');
58
+ const result = path.parse(str);
59
+
60
+ Object.keys(result).forEach((key) => {
61
+ const valInfo = tracker.getData(result[key]);
62
+ expect(valInfo).to.be.null;
63
+ });
64
+ });
65
+ });
66
+ });
67
+
68
+ it('will not propagate if the argument is not tracked', function () {
69
+ simulateRequestScope(function () {
70
+ const str = '/path/to/file.txt';
71
+ const result = path.parse(str);
72
+
73
+ Object.keys(result).forEach((key) => {
74
+ const valInfo = tracker.getData(result[key]);
75
+ expect(valInfo).to.be.null;
76
+ });
77
+ expect(createPropagationEvent).to.not.have.been.called;
78
+ });
79
+ });
80
+
81
+ it('will not propagate if there no event created', function () {
82
+ simulateRequestScope(function () {
83
+ core.config.assess.max_propagation_events = 0;
84
+ const str = trackString('/path/to/file.txt');
85
+ const result = path.parse(str);
86
+
87
+ Object.keys(result).forEach((key) => {
88
+ const valInfo = tracker.getData(result[key]);
89
+ expect(valInfo).to.be.null;
90
+ });
91
+ });
92
+ });
93
+
94
+ it('should propagate tracked dir', function() {
95
+ simulateRequestScope(function () {
96
+ const str = trackString('/path/to/file.txt', {
97
+ tags: {
98
+ UNTRUSTED: [1, 7]
99
+ }
100
+ });
101
+
102
+ const { dir, base, name, ext } = path.parse(str);
103
+ expect(dir).to.be.equal('/path/to');
104
+ expect(tracker.getData(dir).tags).to.deep.equal({
105
+ [UNTRUSTED]: [1, 7]
106
+ });
107
+ expect(tracker.getData(base)).to.be.null;
108
+ expect(tracker.getData(name)).to.be.null;
109
+ expect(tracker.getData(ext)).to.be.null;
110
+ });
111
+ });
112
+
113
+ it('should propagate tracked base', function() {
114
+ simulateRequestScope(function () {
115
+ const str = trackString('/path/to/file.txt', {
116
+ tags: {
117
+ UNTRUSTED: [9, 16]
118
+ }
119
+ });
120
+
121
+ const { dir, base, name, ext } = path.parse(str);
122
+ expect(base).to.be.equal('file.txt');
123
+ expect(tracker.getData(base).tags).to.deep.equal({
124
+ [UNTRUSTED]: [0, 3, 5, 7]
125
+ });
126
+ expect(name).to.be.equal('file');
127
+ expect(tracker.getData(name).tags).to.deep.equal({
128
+ [UNTRUSTED]: [0, 3]
129
+ });
130
+ expect(ext).to.be.equal('.txt');
131
+ expect(tracker.getData(ext).tags).to.deep.equal({
132
+ [UNTRUSTED]: [1, 3]
133
+ });
134
+ expect(tracker.getData(dir)).to.be.null;
135
+ });
136
+ });
137
+
138
+ it('should propagate tracked name', function() {
139
+ simulateRequestScope(function () {
140
+ const str = trackString('/path/to/file.txt', {
141
+ tags: {
142
+ UNTRUSTED: [9, 12]
143
+ }
144
+ });
145
+
146
+ const { dir, base, name, ext } = path.parse(str);
147
+ expect(name).to.be.equal('file');
148
+ expect(tracker.getData(name).tags).to.deep.equal({
149
+ [UNTRUSTED]: [0, 3]
150
+ });
151
+ expect(base).to.be.equal('file.txt');
152
+ expect(tracker.getData(base).tags).to.deep.equal({
153
+ [UNTRUSTED]: [0, 3]
154
+ });
155
+ expect(tracker.getData(dir)).to.be.null;
156
+ expect(tracker.getData(ext)).to.be.null;
157
+ });
158
+ });
159
+
160
+ it('should propagate tracked ext', function() {
161
+ simulateRequestScope(function () {
162
+ const str = trackString('/path/to/file.txt', {
163
+ tags: {
164
+ UNTRUSTED: [14, 16]
165
+ }
166
+ });
167
+
168
+ const { dir, base, name, ext } = path.parse(str);
169
+ expect(ext).to.be.equal('.txt');
170
+ expect(tracker.getData(ext).tags).to.deep.equal({
171
+ [UNTRUSTED]: [1, 3]
172
+ });
173
+ expect(base).to.be.equal('file.txt');
174
+ expect(tracker.getData(base).tags).to.deep.equal({
175
+ [UNTRUSTED]: [5, 7]
176
+ });
177
+ expect(tracker.getData(dir)).to.be.null;
178
+ expect(tracker.getData(name)).to.be.null;
179
+ });
180
+ });
181
+
182
+ it('should propagate multiple tracked properties', function() {
183
+ simulateRequestScope(function () {
184
+ const str = trackString('/path/to/file.txt');
185
+
186
+ const { dir, base, name, ext } = path.parse(str);
187
+ expect(dir).to.be.equal('/path/to');
188
+ expect(tracker.getData(dir).tags).to.deep.equal({
189
+ [UNTRUSTED]: [0, 7]
190
+ });
191
+ expect(base).to.be.equal('file.txt');
192
+ expect(tracker.getData(base).tags).to.deep.equal({
193
+ [UNTRUSTED]: [0, 3, 5, 7]
194
+ });
195
+ expect(name).to.be.equal('file');
196
+ expect(tracker.getData(name).tags).to.deep.equal({
197
+ [UNTRUSTED]: [0, 3]
198
+ });
199
+ expect(ext).to.be.equal('.txt');
200
+ expect(tracker.getData(ext).tags).to.deep.equal({
201
+ [UNTRUSTED]: [1, 3]
202
+ });
203
+ });
204
+ });
205
+
206
+ it('should propagate multiple tag ranges', function() {
207
+ simulateRequestScope(function () {
208
+ const str = trackString('/path/to/file.txt', {
209
+ tags: {
210
+ UNTRUSTED: [0, 7],
211
+ 'FOO': [9, 12],
212
+ 'BAR': [14, 16]
213
+ }
214
+ });
215
+
216
+ const { dir, base, name, ext } = path.parse(str);
217
+ expect(dir).to.be.equal('/path/to');
218
+ expect(tracker.getData(dir).tags).to.deep.equal({
219
+ [UNTRUSTED]: [0, 7]
220
+ });
221
+ expect(base).to.be.equal('file.txt');
222
+ expect(tracker.getData(base).tags).to.deep.equal({
223
+ ['FOO']: [0, 3],
224
+ ['BAR']: [5, 7]
225
+ });
226
+ expect(name).to.be.equal('file');
227
+ expect(tracker.getData(name).tags).to.deep.equal({
228
+ ['FOO']: [0, 3],
229
+ });
230
+ expect(ext).to.be.equal('.txt');
231
+ expect(tracker.getData(ext).tags).to.deep.equal({
232
+ ['BAR']: [1, 3]
233
+ });
234
+ });
235
+ });
236
+ });
237
+ });
238
+ });
@@ -0,0 +1,239 @@
1
+ 'use strict';
2
+
3
+ const sinon = require('sinon');
4
+ const { expect } = require('chai');
5
+ const { initAssessFixture } = require('@contrast/test/fixtures');
6
+ const { DataflowTag: { UNTRUSTED } } = require('@contrast/common');
7
+
8
+ describe('assess dataflow propagation path relative', function () {
9
+ let core, tracker, createPropagationEvent, trackString, simulateRequestScope;
10
+
11
+ beforeEach(function () {
12
+ ({ core, simulateRequestScope, trackString } = initAssessFixture());
13
+ tracker = core.assess.dataflow.tracker;
14
+ createPropagationEvent = sinon.spy(
15
+ core.assess.eventFactory,
16
+ 'createPropagationEvent'
17
+ );
18
+ core.assess.dataflow.propagation.stringInstrumentation.concat.install();
19
+ });
20
+
21
+ ['posix', 'win32'].forEach((os) => {
22
+ describe(os, function () {
23
+ let path;
24
+
25
+ beforeEach(function () {
26
+ path = require('path')[os];
27
+
28
+ core.depHooks.resolve.yields(path);
29
+ const relativeInstr = require('./relative')(core);
30
+ relativeInstr.install();
31
+ });
32
+
33
+ it('should ignore empty string', function () {
34
+ simulateRequestScope(function () {
35
+ const myPath = trackString('');
36
+
37
+ const file = path.relative('/to', myPath);
38
+ const strInfo = tracker.getData(file);
39
+
40
+ expect(strInfo).to.be.null;
41
+ });
42
+ });
43
+
44
+ it('will not propagate if there is no assess context', function () {
45
+ simulateRequestScope(function () {
46
+ const myPath = trackString('/path');
47
+
48
+ const result = path.relative('/to', myPath);
49
+
50
+ expect(tracker.getData(result)).to.be.null;
51
+ }, {});
52
+ });
53
+
54
+ it('will not propagate if there instrumentation is locked', function () {
55
+ simulateRequestScope(function () {
56
+ core.scopes.instrumentation.run({ lock: true }, function () {
57
+ const myPath = trackString('/path');
58
+
59
+ const result = path.relative('/to', myPath);
60
+
61
+ expect(tracker.getData(result)).to.be.null;
62
+ });
63
+ });
64
+ });
65
+
66
+ it('will not propagate if the argument is not tracked', function () {
67
+ simulateRequestScope(function () {
68
+ const myPath = '/path';
69
+
70
+ path.relative('/to', myPath);
71
+
72
+ expect(createPropagationEvent).to.not.have.been.called;
73
+ });
74
+ });
75
+
76
+ it('will not propagate if there no event created', function () {
77
+ simulateRequestScope(function () {
78
+ core.config.assess.max_propagation_events = 0;
79
+ const myPath = trackString('/path');
80
+
81
+ const result = path.relative('/to', myPath);
82
+
83
+ expect(tracker.getData(result)).to.be.null;
84
+ });
85
+ });
86
+
87
+ it('should not propagate if only the first argument is tracked', function () {
88
+ simulateRequestScope(function () {
89
+ const myPath = trackString('/to/dir/..');
90
+
91
+ const result = path.relative(myPath, '/dir/path');
92
+ expect(tracker.getData(result)).to.be.null;
93
+ });
94
+ });
95
+
96
+ it('should not propagate if second argument is tracked but not in result', function () {
97
+ simulateRequestScope(function () {
98
+ const myPath = trackString('/path');
99
+ const result = path.relative('/path', myPath);
100
+ expect(result).to.be.equal('');
101
+ expect(tracker.getData(result)).to.be.null;
102
+ });
103
+ });
104
+
105
+ it('should propagate if second argument is tracked', function () {
106
+ simulateRequestScope(function () {
107
+ const myPath = trackString('/my/path');
108
+
109
+ const result = path.relative('/my', myPath);
110
+ const strInfo = tracker.getData(result);
111
+
112
+ expect(result).to.be.equal('path');
113
+ expect(strInfo.tags).to.deep.equal({
114
+ [UNTRUSTED]: [0, 3],
115
+ });
116
+ });
117
+ });
118
+
119
+ it('should not include file extension dots in tag ranges', function () {
120
+ simulateRequestScope(function () {
121
+ const myPath = trackString('/my/path/to/file.png');
122
+
123
+ const result = path.relative('/my', myPath);
124
+ const strInfo = tracker.getData(result);
125
+
126
+ if (os === 'win32') {
127
+ expect(result).to.be.equal('path\\to\\file.png');
128
+ expect(strInfo.tags).to.deep.equal({
129
+ [UNTRUSTED]: [0, 3, 5, 6, 8, 11, 13, 15],
130
+ });
131
+ } else {
132
+ expect(result).to.be.equal('path/to/file.png');
133
+ expect(strInfo.tags).to.deep.equal({
134
+ [UNTRUSTED]: [0, 11, 13, 15],
135
+ });
136
+ }
137
+ });
138
+ });
139
+
140
+ it('should propagate if first argument is absolute and second is relative ', function () {
141
+ simulateRequestScope(function () {
142
+ const myPath = trackString('/my/path/to/../file');
143
+
144
+ const result = path.relative('/my/path/to/', myPath);
145
+ const strInfo = tracker.getData(result);
146
+
147
+ if (os === 'win32') {
148
+ expect(result).to.be.equal('..\\file');
149
+ expect(strInfo.tags).to.deep.equal({
150
+ [UNTRUSTED]: [0, 1, 3, 6],
151
+ });
152
+ } else {
153
+ expect(result).to.be.equal('../file');
154
+ expect(strInfo.tags).to.deep.equal({
155
+ [UNTRUSTED]: [0, 6],
156
+ });
157
+ }
158
+ });
159
+ });
160
+
161
+ it('should propagate if first argument is relative and second is absolute ', function () {
162
+ simulateRequestScope(function () {
163
+ const myPath = trackString('/my/path');
164
+
165
+ const result = path.relative('/path/..', myPath);
166
+ const strInfo = tracker.getData(result);
167
+
168
+ if (os === 'win32') {
169
+ expect(result).to.be.equal('my\\path');
170
+ expect(strInfo.tags).to.deep.equal({
171
+ [UNTRUSTED]: [0, 1, 3, 6],
172
+ });
173
+ } else {
174
+ expect(result).to.be.equal('my/path');
175
+ expect(strInfo.tags).to.deep.equal({
176
+ [UNTRUSTED]: [0, 6],
177
+ });
178
+ }
179
+ });
180
+ });
181
+
182
+ it('should propagate if first and second arguments are relative ', function () {
183
+ simulateRequestScope(function () {
184
+ const myPath = trackString('/../path');
185
+
186
+ const result = path.relative('/path/..', myPath);
187
+ const strInfo = tracker.getData(result);
188
+
189
+ expect(result).to.be.equal('path');
190
+ expect(strInfo.tags).to.deep.equal({
191
+ [UNTRUSTED]: [0, 3],
192
+ });
193
+ });
194
+ });
195
+
196
+ it('should propagate if second argument is partially tracked', function () {
197
+ simulateRequestScope(function () {
198
+ const myPath = trackString('/path/to');
199
+
200
+ const result = path.relative('/my', '/my'.concat(myPath));
201
+ const strInfo = tracker.getData(result);
202
+
203
+ if (os === 'win32') {
204
+ expect(result).to.be.equal('path\\to');
205
+ expect(strInfo.tags).to.deep.equal({
206
+ [UNTRUSTED]: [0, 3, 5, 6],
207
+ });
208
+ } else {
209
+ expect(result).to.be.equal('path/to');
210
+ expect(strInfo.tags).to.deep.equal({
211
+ [UNTRUSTED]: [0, 6],
212
+ });
213
+ }
214
+ });
215
+ });
216
+
217
+ it('should propagate multiple tag ranges', function () {
218
+ simulateRequestScope(function () {
219
+ const myPath = trackString('/my/path', {
220
+ tags: {
221
+ UNTRUSTED: [0, 7],
222
+ 'FOO': [1, 2],
223
+ 'BAR': [1, 7]
224
+ }
225
+ });
226
+
227
+ const result = path.relative('/my', myPath);
228
+ const strInfo = tracker.getData(result);
229
+
230
+ expect(result).to.be.equal('path');
231
+ expect(strInfo.tags).to.deep.equal({
232
+ [UNTRUSTED]: [0, 3],
233
+ ['BAR']: [0, 3]
234
+ });
235
+ });
236
+ });
237
+ });
238
+ });
239
+ });
@@ -0,0 +1,158 @@
1
+ 'use strict';
2
+
3
+ const { expect } = require('chai');
4
+ const { initAssessFixture } = require('@contrast/test/fixtures');
5
+ const { DataflowTag: { UNTRUSTED } } = require('@contrast/common');
6
+
7
+ describe('assess dataflow propagation path toNamespacedPath', function () {
8
+ let core, tracker, trackString, simulateRequestScope;
9
+
10
+ beforeEach(function () {
11
+ ({ core, simulateRequestScope, trackString } = initAssessFixture());
12
+ tracker = core.assess.dataflow.tracker;
13
+ core.assess.dataflow.propagation.stringInstrumentation.concat.install();
14
+ });
15
+
16
+ describe('win32', function () {
17
+ let path;
18
+
19
+ beforeEach(function () {
20
+ path = require('path')['win32'];
21
+
22
+ core.depHooks.resolve.yields(path);
23
+ const toNamespacedPathInstr = require('./toNamespacedPath')(core);
24
+ toNamespacedPathInstr.install();
25
+ });
26
+
27
+ it('should ignore empty string', function () {
28
+ simulateRequestScope(function () {
29
+ const myPath = trackString('');
30
+
31
+ const result = path.toNamespacedPath(myPath);
32
+ const strInfo = tracker.getData(result);
33
+
34
+ expect(strInfo).to.be.null;
35
+ });
36
+ });
37
+
38
+ it('will not propagate if there is no assess context', function () {
39
+ simulateRequestScope(function () {
40
+ const myPath = trackString('C:\\path\\to\\file.txt');
41
+
42
+ const result = path.toNamespacedPath(myPath);
43
+
44
+ expect(tracker.getData(result)).to.be.null;
45
+ }, {});
46
+ });
47
+
48
+ it('will not propagate if there instrumentation is locked', function () {
49
+ simulateRequestScope(function () {
50
+ core.scopes.instrumentation.run({ lock: true }, function () {
51
+ const myPath = trackString('C:\\path\\to\\file.txt');
52
+
53
+ const result = path.toNamespacedPath(myPath);
54
+
55
+ expect(tracker.getData(result)).to.be.null;
56
+ });
57
+ });
58
+ });
59
+
60
+ it('will not propagate if the argument is not tracked', function () {
61
+ simulateRequestScope(function () {
62
+ const myPath = 'C:\\path\\to\\file.txt';
63
+
64
+ const result = path.toNamespacedPath(myPath);
65
+
66
+ expect(tracker.getData(result)).to.be.null;
67
+ });
68
+ });
69
+
70
+ it('will not propagate if there no event created', function () {
71
+ simulateRequestScope(function () {
72
+ core.config.assess.max_propagation_events = 0;
73
+ const myPath = trackString('C:\\path\\to\\file.txt');
74
+
75
+ const result = path.toNamespacedPath(myPath);
76
+
77
+ expect(tracker.getData(result)).to.be.null;
78
+ });
79
+ });
80
+
81
+ it('should propagate if entire path is tracked', function () {
82
+ simulateRequestScope(function () {
83
+ const myPath = trackString('C:\\path\\to\\file.txt');
84
+
85
+ const result = path.toNamespacedPath(myPath);
86
+ const strInfo = tracker.getData(result);
87
+
88
+ expect(result).to.be.equal('\\\\?\\C:\\path\\to\\file.txt');
89
+ expect(strInfo.tags).to.deep.equal({
90
+ [UNTRUSTED]: [4, 18, 20, 22]
91
+ });
92
+ });
93
+ });
94
+
95
+ it('should propagate if partial path is tracked ', function () {
96
+ simulateRequestScope(function () {
97
+ const myPath = trackString('file.txt');
98
+
99
+ const result = path.toNamespacedPath('C:\\path\\to\\'.concat(myPath));
100
+ const strInfo = tracker.getData(result);
101
+
102
+ expect(result).to.be.equal('\\\\?\\C:\\path\\to\\file.txt');
103
+ expect(strInfo.tags).to.deep.equal({
104
+ [UNTRUSTED]: [15, 18, 20, 22],
105
+ });
106
+ });
107
+ });
108
+
109
+ it('should propagate multiple tag ranges ', function () {
110
+ simulateRequestScope(function () {
111
+ const myPath = trackString('C:\\path\\to\\file.txt', {
112
+ tags: {
113
+ UNTRUSTED: [0, 18],
114
+ 'FOO': [3, 14],
115
+ 'BAR': [16, 18]
116
+ }
117
+ });
118
+
119
+ const result = path.toNamespacedPath(myPath);
120
+ const strInfo = tracker.getData(result);
121
+
122
+ expect(result).to.be.equal('\\\\?\\C:\\path\\to\\file.txt');
123
+ expect(strInfo.tags).to.deep.equal({
124
+ [UNTRUSTED]: [4, 18, 20, 22],
125
+ ['FOO']: [7, 18],
126
+ ['BAR']: [20, 22],
127
+ });
128
+ });
129
+ });
130
+ });
131
+
132
+ describe('posix', function() {
133
+ let path;
134
+ beforeEach(function () {
135
+ path = require('path')['posix'];
136
+
137
+ core.depHooks.resolve.yields(path);
138
+ const toNamespacedPathInstr = require('./toNamespacedPath')(core);
139
+ toNamespacedPathInstr.install();
140
+ });
141
+
142
+ // https://nodejs.org/api/path.html#pathtonamespacedpathpath
143
+ // On POSIX systems, the method is non-operational and always returns path without modifications.
144
+ it('should propagate if tracked', function () {
145
+ simulateRequestScope(function () {
146
+ const myPath = trackString('/path/to/file.txt');
147
+
148
+ const result = path.toNamespacedPath(myPath);
149
+ const strInfo = tracker.getData(result);
150
+
151
+ expect(result).to.be.equal('/path/to/file.txt');
152
+ expect(strInfo.tags).to.deep.equal({
153
+ [UNTRUSTED]: [0, 16]
154
+ });
155
+ });
156
+ });
157
+ });
158
+ });
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ const { expect } = require('chai');
4
+ const sinon = require('sinon');
5
+ const { initAssessFixture } = require('@contrast/test/fixtures');
6
+
7
+ describe('assess dataflow propagation pug', function () {
8
+ let core, simulateRequestScope, plugins, pugMock, patchedPug;
9
+
10
+ beforeEach(function () {
11
+ ({ core, simulateRequestScope } = initAssessFixture());
12
+ core.rewriter.install('assess');
13
+
14
+ pugMock = {
15
+ compile(str, options) {
16
+ // this is mocked enough to be simulated in unit tests, but
17
+ // we also have integration tests to be sure
18
+ let result = str;
19
+ plugins.forEach((p) => {
20
+ result = p.postCodeGen(result, null);
21
+ });
22
+ return result;
23
+ }
24
+ };
25
+ sinon.spy(core.rewriter, 'rewriteSync');
26
+ sinon.spy(core.patcher, 'patch');
27
+
28
+ require('.')(core).install();
29
+ patchedPug = core.depHooks.resolve.yield(pugMock)[0];
30
+ core.patcher.patch.resetHistory();
31
+
32
+ plugins = [];
33
+ });
34
+
35
+ [
36
+ {
37
+ input: '1 + 1',
38
+ expected: 'ContrastMethods.add(1, 1);\n',
39
+ },
40
+ {
41
+ input: 'const foot = 12;',
42
+ expected: 'const foot = 12;\n',
43
+ }
44
+ ].forEach(({ input, expected }) => {
45
+ it('plugin should return rewritten value on success', function () {
46
+ let result;
47
+
48
+ simulateRequestScope(() => {
49
+ result = patchedPug.compile(input, { plugins });
50
+ });
51
+
52
+ expect(result).to.equal(expected);
53
+ });
54
+ });
55
+ });