@contrast/assess 1.46.1 → 1.46.3
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.
- package/package.json +14 -11
- package/lib/crypto-analysis/install/crypto.test.js +0 -146
- package/lib/crypto-analysis/install/math.test.js +0 -65
- package/lib/dataflow/index.test.js +0 -36
- package/lib/dataflow/propagation/index.test.js +0 -103
- package/lib/dataflow/propagation/install/JSON/index.test.js +0 -50
- package/lib/dataflow/propagation/install/JSON/parse-fn.test.js +0 -232
- package/lib/dataflow/propagation/install/JSON/parse.test.js +0 -968
- package/lib/dataflow/propagation/install/JSON/stringify.test.js +0 -265
- package/lib/dataflow/propagation/install/array-prototype-join.test.js +0 -106
- package/lib/dataflow/propagation/install/buffer.test.js +0 -112
- package/lib/dataflow/propagation/install/contrast-methods/add.test.js +0 -94
- package/lib/dataflow/propagation/install/contrast-methods/index.test.js +0 -49
- package/lib/dataflow/propagation/install/contrast-methods/number.test.js +0 -50
- package/lib/dataflow/propagation/install/contrast-methods/string.test.js +0 -148
- package/lib/dataflow/propagation/install/contrast-methods/tag.test.js +0 -145
- package/lib/dataflow/propagation/install/decode-uri-component.test.js +0 -78
- package/lib/dataflow/propagation/install/ejs/escape-xml.test.js +0 -69
- package/lib/dataflow/propagation/install/ejs/template.test.js +0 -62
- package/lib/dataflow/propagation/install/encode-uri.test.js +0 -83
- package/lib/dataflow/propagation/install/escape-html.test.js +0 -71
- package/lib/dataflow/propagation/install/escape.test.js +0 -73
- package/lib/dataflow/propagation/install/fastify-send.test.js +0 -42
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.test.js +0 -71
- package/lib/dataflow/propagation/install/isnumeric-0.test.js +0 -58
- package/lib/dataflow/propagation/install/joi/any.test.js +0 -270
- package/lib/dataflow/propagation/install/joi/array.test.js +0 -912
- package/lib/dataflow/propagation/install/joi/boolean.test.js +0 -103
- package/lib/dataflow/propagation/install/joi/expression.test.js +0 -76
- package/lib/dataflow/propagation/install/joi/index.test.js +0 -39
- package/lib/dataflow/propagation/install/joi/number.test.js +0 -103
- package/lib/dataflow/propagation/install/joi/object.test.js +0 -119
- package/lib/dataflow/propagation/install/joi/ref.test.js +0 -607
- package/lib/dataflow/propagation/install/joi/string-schema.test.js +0 -513
- package/lib/dataflow/propagation/install/mongoose/index.test.js +0 -42
- package/lib/dataflow/propagation/install/mongoose/schema-map.test.js +0 -348
- package/lib/dataflow/propagation/install/mongoose/schema-mixed.test.js +0 -511
- package/lib/dataflow/propagation/install/mongoose/schema-string.test.js +0 -199
- package/lib/dataflow/propagation/install/mustache-escape.test.js +0 -62
- package/lib/dataflow/propagation/install/mysql-connection-escape.test.js +0 -74
- package/lib/dataflow/propagation/install/parse-int.test.js +0 -48
- package/lib/dataflow/propagation/install/path/basename.test.js +0 -143
- package/lib/dataflow/propagation/install/path/dirname.test.js +0 -167
- package/lib/dataflow/propagation/install/path/extname.test.js +0 -141
- package/lib/dataflow/propagation/install/path/format.test.js +0 -250
- package/lib/dataflow/propagation/install/path/index.test.js +0 -45
- package/lib/dataflow/propagation/install/path/join-and-resolve.test.js +0 -485
- package/lib/dataflow/propagation/install/path/normalize.test.js +0 -176
- package/lib/dataflow/propagation/install/path/parse.test.js +0 -238
- package/lib/dataflow/propagation/install/path/relative.test.js +0 -239
- package/lib/dataflow/propagation/install/path/toNamespacedPath.test.js +0 -158
- package/lib/dataflow/propagation/install/pug/index.test.js +0 -55
- package/lib/dataflow/propagation/install/pug-runtime-escape.test.js +0 -69
- package/lib/dataflow/propagation/install/querystring/escape.test.js +0 -63
- package/lib/dataflow/propagation/install/querystring/index.test.js +0 -40
- package/lib/dataflow/propagation/install/querystring/parse.test.js +0 -272
- package/lib/dataflow/propagation/install/querystring/stringify.test.js +0 -301
- package/lib/dataflow/propagation/install/reg-exp-prototype-exec.test.js +0 -283
- package/lib/dataflow/propagation/install/send.test.js +0 -63
- package/lib/dataflow/propagation/install/sequelize/query-generator.test.js +0 -74
- package/lib/dataflow/propagation/install/sequelize/sql-string.test.js +0 -119
- package/lib/dataflow/propagation/install/sql-template-strings.test.js +0 -100
- package/lib/dataflow/propagation/install/string/concat.test.js +0 -145
- package/lib/dataflow/propagation/install/string/format-methods.test.js +0 -74
- package/lib/dataflow/propagation/install/string/html-methods.test.js +0 -177
- package/lib/dataflow/propagation/install/string/index.test.js +0 -103
- package/lib/dataflow/propagation/install/string/match-all.test.js +0 -412
- package/lib/dataflow/propagation/install/string/match.test.js +0 -374
- package/lib/dataflow/propagation/install/string/replace.test.js +0 -601
- package/lib/dataflow/propagation/install/string/slice.test.js +0 -278
- package/lib/dataflow/propagation/install/string/split.test.js +0 -513
- package/lib/dataflow/propagation/install/string/substring.test.js +0 -251
- package/lib/dataflow/propagation/install/string/trim.test.js +0 -135
- package/lib/dataflow/propagation/install/unescape.test.js +0 -78
- package/lib/dataflow/propagation/install/url/domain-parsers.test.js +0 -63
- package/lib/dataflow/propagation/install/url/parse.test.js +0 -391
- package/lib/dataflow/propagation/install/url/searchParams.test.js +0 -538
- package/lib/dataflow/propagation/install/url/url.test.js +0 -466
- package/lib/dataflow/propagation/install/util-format.test.js +0 -336
- package/lib/dataflow/propagation/install/validator/hooks.test.js +0 -211
- package/lib/dataflow/sinks/index.test.js +0 -78
- package/lib/dataflow/sinks/install/child-process.test.js +0 -338
- package/lib/dataflow/sinks/install/eval.test.js +0 -95
- package/lib/dataflow/sinks/install/express/index.test.js +0 -33
- package/lib/dataflow/sinks/install/express/reflected-xss.test.js +0 -109
- package/lib/dataflow/sinks/install/express/unvalidated-redirect.test.js +0 -144
- package/lib/dataflow/sinks/install/fastify/index.test.js +0 -32
- package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.test.js +0 -130
- package/lib/dataflow/sinks/install/fs.test.js +0 -138
- package/lib/dataflow/sinks/install/function.test.js +0 -103
- package/lib/dataflow/sinks/install/hapi/index.test.js +0 -32
- package/lib/dataflow/sinks/install/hapi/unvalidated-redirect.test.js +0 -130
- package/lib/dataflow/sinks/install/http/index.test.js +0 -33
- package/lib/dataflow/sinks/install/http/request.test.js +0 -184
- package/lib/dataflow/sinks/install/http/server-response.test.js +0 -160
- package/lib/dataflow/sinks/install/koa/index.test.js +0 -32
- package/lib/dataflow/sinks/install/koa/unvalidated-redirect.test.js +0 -200
- package/lib/dataflow/sinks/install/libxmljs.test.js +0 -158
- package/lib/dataflow/sinks/install/marsdb.test.js +0 -166
- package/lib/dataflow/sinks/install/mongodb.test.js +0 -617
- package/lib/dataflow/sinks/install/mssql.test.js +0 -134
- package/lib/dataflow/sinks/install/mysql.test.js +0 -224
- package/lib/dataflow/sinks/install/node-serialize.test.js +0 -83
- package/lib/dataflow/sinks/install/postgres.test.js +0 -152
- package/lib/dataflow/sinks/install/restify.test.js +0 -140
- package/lib/dataflow/sinks/install/sequelize.test.js +0 -100
- package/lib/dataflow/sinks/install/sqlite3.test.js +0 -118
- package/lib/dataflow/sinks/install/vm.test.js +0 -326
- package/lib/dataflow/sources/handler.test.js +0 -501
- package/lib/dataflow/sources/index.test.js +0 -60
- package/lib/dataflow/sources/install/body-parser1.test.js +0 -244
- package/lib/dataflow/sources/install/busboy.test.js +0 -152
- package/lib/dataflow/sources/install/cookie-parser1.test.js +0 -141
- package/lib/dataflow/sources/install/express/params.test.js +0 -110
- package/lib/dataflow/sources/install/express/parsedUrl.test.js +0 -107
- package/lib/dataflow/sources/install/fastify/fastify.test.js +0 -207
- package/lib/dataflow/sources/install/fastify/index.test.js +0 -33
- package/lib/dataflow/sources/install/formidable1.test.js +0 -119
- package/lib/dataflow/sources/install/graphql-http.test.js +0 -133
- package/lib/dataflow/sources/install/hapi/hapi.test.js +0 -171
- package/lib/dataflow/sources/install/hapi/index.test.js +0 -33
- package/lib/dataflow/sources/install/http.test.js +0 -149
- package/lib/dataflow/sources/install/koa/index.test.js +0 -40
- package/lib/dataflow/sources/install/koa/koa-bodyparsers.test.js +0 -160
- package/lib/dataflow/sources/install/koa/koa-multer.test.js +0 -197
- package/lib/dataflow/sources/install/koa/koa-routers.test.js +0 -146
- package/lib/dataflow/sources/install/koa/koa2.test.js +0 -145
- package/lib/dataflow/sources/install/multer1.test.js +0 -143
- package/lib/dataflow/sources/install/qs6.test.js +0 -131
- package/lib/dataflow/sources/install/querystring.test.js +0 -82
- package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.test.js +0 -86
- package/lib/dataflow/sources/install/restify/index.test.js +0 -38
- package/lib/dataflow/sources/install/restify/jsonBodyParser.test.js +0 -140
- package/lib/dataflow/sources/install/restify/router.test.js +0 -81
- package/lib/dataflow/tag-utils-complete.test.js +0 -27
- package/lib/dataflow/tag-utils.test.js +0 -192
- package/lib/dataflow/tracker.test.js +0 -216
- package/lib/dataflow/utils/is-safe-content-type.test.js +0 -16
- package/lib/dataflow/utils/is-vulnerable.test.js +0 -115
- package/lib/event-factory.test.js +0 -326
- package/lib/get-policy.test.js +0 -194
- package/lib/get-source-context.test.js +0 -161
- package/lib/index.test.js +0 -45
- package/lib/make-source-context.test.js +0 -50
- package/lib/response-scanning/handlers/index.test.js +0 -419
- package/lib/response-scanning/handlers/utils.test.js +0 -380
- package/lib/response-scanning/index.test.js +0 -41
- package/lib/response-scanning/install/http.test.js +0 -175
- package/lib/rule-scopes.test.js +0 -27
- package/lib/sampler/common.test.js +0 -101
- package/lib/sampler/index.test.js +0 -313
- package/lib/session-configuration/handlers.test.js +0 -84
- package/lib/session-configuration/index.test.js +0 -36
- package/lib/session-configuration/install/express-session.test.js +0 -218
- package/lib/session-configuration/install/fastify-cookie.test.js +0 -63
- package/lib/session-configuration/install/hapi.test.js +0 -269
- package/lib/session-configuration/install/koa.test.js +0 -92
|
@@ -1,485 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { DataflowTag: { UNTRUSTED, CUSTOM_ENCODED } } = require('@contrast/common');
|
|
4
|
-
const { expect } = require('chai');
|
|
5
|
-
const sinon = require('sinon');
|
|
6
|
-
const { initAssessFixture } = require('@contrast/test/fixtures');
|
|
7
|
-
|
|
8
|
-
describe('assess dataflow propagation path', function () {
|
|
9
|
-
let core, tracker, createPropagationEvent, trackString, simulateRequestScope;
|
|
10
|
-
|
|
11
|
-
beforeEach(function () {
|
|
12
|
-
({
|
|
13
|
-
core,
|
|
14
|
-
simulateRequestScope,
|
|
15
|
-
trackString
|
|
16
|
-
} = initAssessFixture());
|
|
17
|
-
tracker = core.assess.dataflow.tracker;
|
|
18
|
-
createPropagationEvent = sinon.spy(core.assess.eventFactory, 'createPropagationEvent');
|
|
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 joinAndResolveInstr = require('./join-and-resolve')(core);
|
|
30
|
-
joinAndResolveInstr.install();
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
['join', 'resolve'].forEach((method) => {
|
|
34
|
-
describe(`${method} common checks`, function () {
|
|
35
|
-
|
|
36
|
-
it('should ignore empty strings', function () {
|
|
37
|
-
simulateRequestScope(function () {
|
|
38
|
-
const emptyStr = trackString('');
|
|
39
|
-
|
|
40
|
-
const result1 = path[method](...[emptyStr, emptyStr, emptyStr]);
|
|
41
|
-
const result2 = path[method]();
|
|
42
|
-
|
|
43
|
-
expect(tracker.getData(result1)).to.be.null;
|
|
44
|
-
expect(tracker.getData(result2)).to.be.null;
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it('will not propagate if there is no assess policy in request context', function () {
|
|
49
|
-
simulateRequestScope(function () {
|
|
50
|
-
const seg1 = trackString('/path');
|
|
51
|
-
const seg2 = trackString('/to');
|
|
52
|
-
const seg3 = trackString('/file');
|
|
53
|
-
|
|
54
|
-
const result = path[method](seg1, seg2, seg3);
|
|
55
|
-
|
|
56
|
-
expect(tracker.getData(result)).to.be.null;
|
|
57
|
-
}, { assess: { policy: null } });
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('will not propagate if there instrumentation is locked', function () {
|
|
61
|
-
simulateRequestScope(function () {
|
|
62
|
-
core.scopes.instrumentation.run({ lock: true }, function () {
|
|
63
|
-
const seg1 = trackString('/path');
|
|
64
|
-
const seg2 = trackString('/to');
|
|
65
|
-
const seg3 = trackString('/file');
|
|
66
|
-
|
|
67
|
-
const result = path[method](seg1, seg2, seg3);
|
|
68
|
-
|
|
69
|
-
expect(tracker.getData(result)).to.be.null;
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it('will not propagate if the argument is not tracked', function () {
|
|
75
|
-
simulateRequestScope(function () {
|
|
76
|
-
const seg1 = '/path';
|
|
77
|
-
const seg2 = '/to';
|
|
78
|
-
const seg3 = '/file';
|
|
79
|
-
|
|
80
|
-
path[method](seg1, seg2, seg3);
|
|
81
|
-
|
|
82
|
-
expect(createPropagationEvent).to.not.have.been.called;
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('will not propagate if there no event created', function () {
|
|
87
|
-
simulateRequestScope(function () {
|
|
88
|
-
core.config.assess.max_propagation_events = 0;
|
|
89
|
-
const seg1 = trackString('/path');
|
|
90
|
-
const seg2 = trackString('/to');
|
|
91
|
-
const seg3 = trackString('/file');
|
|
92
|
-
|
|
93
|
-
const result = path[method](seg1, seg2, seg3);
|
|
94
|
-
|
|
95
|
-
expect(tracker.getData(result)).to.be.null;
|
|
96
|
-
});
|
|
97
|
-
});
|
|
98
|
-
|
|
99
|
-
it('should contain 2 parent events on result when there are 2 args to function that had tag ranges', function () {
|
|
100
|
-
simulateRequestScope(function () {
|
|
101
|
-
const seg1 = trackString('/root');
|
|
102
|
-
const seg2 = trackString('path/to/file');
|
|
103
|
-
|
|
104
|
-
const result = path[method](seg1, seg2);
|
|
105
|
-
const strInfo = tracker.getData(result);
|
|
106
|
-
|
|
107
|
-
expect(strInfo.history).to.have.lengthOf(2);
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
[
|
|
112
|
-
{
|
|
113
|
-
name: 'should move tags when 2 diff args have partially tracked segments',
|
|
114
|
-
args: [
|
|
115
|
-
() => trackString('/path/to/the/file', {
|
|
116
|
-
tags: {
|
|
117
|
-
[UNTRUSTED]: [1, 4]
|
|
118
|
-
}
|
|
119
|
-
}),
|
|
120
|
-
() => trackString('path/to/new/file', {
|
|
121
|
-
tags: {
|
|
122
|
-
[CUSTOM_ENCODED]: [5, 10]
|
|
123
|
-
}
|
|
124
|
-
})
|
|
125
|
-
],
|
|
126
|
-
expectedWin32: {
|
|
127
|
-
[UNTRUSTED]: [1, 4],
|
|
128
|
-
[CUSTOM_ENCODED]: [23, 24, 26, 28]
|
|
129
|
-
},
|
|
130
|
-
expectedPosix: {
|
|
131
|
-
[UNTRUSTED]: [1, 4],
|
|
132
|
-
[CUSTOM_ENCODED]: [23, 28]
|
|
133
|
-
}
|
|
134
|
-
},
|
|
135
|
-
{
|
|
136
|
-
name: 'should properly move tags when there is bunch of `../` ',
|
|
137
|
-
args: [
|
|
138
|
-
() => trackString('/path-a/path-b', {
|
|
139
|
-
tags: {
|
|
140
|
-
[UNTRUSTED]: [2, 9]
|
|
141
|
-
}
|
|
142
|
-
}),
|
|
143
|
-
() => trackString('../../../../file.txt', {
|
|
144
|
-
tags: {
|
|
145
|
-
[CUSTOM_ENCODED]: [12, 19]
|
|
146
|
-
}
|
|
147
|
-
})
|
|
148
|
-
],
|
|
149
|
-
expectedWin32: {
|
|
150
|
-
[UNTRUSTED]: [1, 4],
|
|
151
|
-
[CUSTOM_ENCODED]: [23, 24, 26, 28]
|
|
152
|
-
},
|
|
153
|
-
expectedPosix: {
|
|
154
|
-
[UNTRUSTED]: [1, 4],
|
|
155
|
-
[CUSTOM_ENCODED]: [23, 28]
|
|
156
|
-
},
|
|
157
|
-
expected: {
|
|
158
|
-
[CUSTOM_ENCODED]: [1, 4, 6, 8]
|
|
159
|
-
}
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
name: 'should properly move tags when segments have duplicate names',
|
|
163
|
-
args: [
|
|
164
|
-
() => trackString('/path/path', {
|
|
165
|
-
tags: {
|
|
166
|
-
[UNTRUSTED]: [2, 7]
|
|
167
|
-
}
|
|
168
|
-
}),
|
|
169
|
-
() => trackString('path/path', {
|
|
170
|
-
tags: {
|
|
171
|
-
[CUSTOM_ENCODED]: [1, 6]
|
|
172
|
-
}
|
|
173
|
-
})
|
|
174
|
-
],
|
|
175
|
-
expectedWin32: {
|
|
176
|
-
[UNTRUSTED]: [2, 4, 6, 7],
|
|
177
|
-
[CUSTOM_ENCODED]: [12, 14, 16, 17]
|
|
178
|
-
},
|
|
179
|
-
expectedPosix: {
|
|
180
|
-
[UNTRUSTED]: [2, 7],
|
|
181
|
-
[CUSTOM_ENCODED]: [12, 17]
|
|
182
|
-
}
|
|
183
|
-
},
|
|
184
|
-
{
|
|
185
|
-
name: 'should properly move tags when there is `./` in the middle of the path',
|
|
186
|
-
args: [
|
|
187
|
-
() => trackString('/path/a/bb', {
|
|
188
|
-
tags: {
|
|
189
|
-
[UNTRUSTED]: [2, 8]
|
|
190
|
-
}
|
|
191
|
-
}),
|
|
192
|
-
() => trackString('some/./ccc/dddd', {
|
|
193
|
-
tags: {
|
|
194
|
-
[CUSTOM_ENCODED]: [3, 12]
|
|
195
|
-
}
|
|
196
|
-
})
|
|
197
|
-
],
|
|
198
|
-
expectedPosix: {
|
|
199
|
-
[UNTRUSTED]: [2, 8],
|
|
200
|
-
[CUSTOM_ENCODED]: [14, 21]
|
|
201
|
-
},
|
|
202
|
-
expectedWin32: {
|
|
203
|
-
[UNTRUSTED]: [2, 4, 6, 6, 8, 8],
|
|
204
|
-
[CUSTOM_ENCODED]: [14, 14, 16, 18, 20, 21]
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
name: 'should properly move tags when there is a folder back',
|
|
209
|
-
args: [
|
|
210
|
-
() => trackString('/path/a/bb', {
|
|
211
|
-
tags: {
|
|
212
|
-
[UNTRUSTED]: [2, 8]
|
|
213
|
-
}
|
|
214
|
-
}),
|
|
215
|
-
() => trackString('some/../ccc/dddd', {
|
|
216
|
-
tags: {
|
|
217
|
-
[CUSTOM_ENCODED]: [3, 12]
|
|
218
|
-
}
|
|
219
|
-
})
|
|
220
|
-
],
|
|
221
|
-
expectedPosix: {
|
|
222
|
-
[UNTRUSTED]: [2, 8],
|
|
223
|
-
[CUSTOM_ENCODED]: [10, 15]
|
|
224
|
-
},
|
|
225
|
-
expectedWin32: {
|
|
226
|
-
[UNTRUSTED]: [2, 4, 6, 6, 8, 8],
|
|
227
|
-
[CUSTOM_ENCODED]: [11, 13, 15, 15]
|
|
228
|
-
}
|
|
229
|
-
},
|
|
230
|
-
{
|
|
231
|
-
name: 'should properly move tags if `.` and `..` were tracked',
|
|
232
|
-
args: [
|
|
233
|
-
() => trackString('/path/to/the/../file/gone/..', {
|
|
234
|
-
tags: {
|
|
235
|
-
[UNTRUSTED]: [9, 18]
|
|
236
|
-
}
|
|
237
|
-
}),
|
|
238
|
-
() => trackString('path/./////to/the/new/file', {
|
|
239
|
-
tags: {
|
|
240
|
-
[CUSTOM_ENCODED]: [0, 15]
|
|
241
|
-
}
|
|
242
|
-
})
|
|
243
|
-
],
|
|
244
|
-
expectedPosix: {
|
|
245
|
-
[UNTRUSTED]: [8, 11],
|
|
246
|
-
[CUSTOM_ENCODED]: [14, 23]
|
|
247
|
-
},
|
|
248
|
-
expectedWin32: {
|
|
249
|
-
[UNTRUSTED]: [9, 11],
|
|
250
|
-
[CUSTOM_ENCODED]: [14, 17, 19, 20, 22, 23]
|
|
251
|
-
}
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
name: 'should not track path if tracked part is removed because of a ..',
|
|
255
|
-
args: [
|
|
256
|
-
() => 'path/to/',
|
|
257
|
-
() => trackString('file.txt'),
|
|
258
|
-
() => '..'
|
|
259
|
-
],
|
|
260
|
-
expectedPosix: undefined,
|
|
261
|
-
expectedWin32: undefined
|
|
262
|
-
},
|
|
263
|
-
{
|
|
264
|
-
name: 'should properly track segments that contain 0 length strings and ./',
|
|
265
|
-
args: [
|
|
266
|
-
() => trackString('/path'),
|
|
267
|
-
() => trackString(''),
|
|
268
|
-
() => trackString('./foo'),
|
|
269
|
-
() => trackString('bar.txt')
|
|
270
|
-
],
|
|
271
|
-
expectedPosix: {
|
|
272
|
-
[UNTRUSTED]: [0, 8, 10, 12, 14, 16],
|
|
273
|
-
},
|
|
274
|
-
expectedWin32: {
|
|
275
|
-
[UNTRUSTED]: [1, 4, 6, 8, 10, 12, 14, 16],
|
|
276
|
-
}
|
|
277
|
-
},
|
|
278
|
-
].forEach(({ name, args, expected, expectedWin32, expectedPosix }) => {
|
|
279
|
-
it(name, function () {
|
|
280
|
-
simulateRequestScope(function () {
|
|
281
|
-
const result = path[method](...args.map(a => a()));
|
|
282
|
-
const strInfo = tracker.getData(result);
|
|
283
|
-
if (os === 'win32') {
|
|
284
|
-
if (method === 'resolve' && process.platform === 'win32') {
|
|
285
|
-
// resolve will prepend C:\ or some other drive letter
|
|
286
|
-
// in front of the root dir so we need to modify
|
|
287
|
-
// the expected tags
|
|
288
|
-
const expectedTags = expected || expectedWin32;
|
|
289
|
-
expectedTags && Object.keys(expectedTags).forEach((key) => {
|
|
290
|
-
expectedTags[key] = expectedTags[key].map(r => r + 2);
|
|
291
|
-
});
|
|
292
|
-
expect(strInfo?.tags).to.eql(expectedTags);
|
|
293
|
-
} else {
|
|
294
|
-
expect(strInfo?.tags).to.eql(expected || expectedWin32);
|
|
295
|
-
}
|
|
296
|
-
} else {
|
|
297
|
-
expect(strInfo?.tags).to.eql(expected || expectedPosix);
|
|
298
|
-
}
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
});
|
|
302
|
-
});
|
|
303
|
-
|
|
304
|
-
it('throw error if part of join is not a string', function () {
|
|
305
|
-
simulateRequestScope(function () {
|
|
306
|
-
const segment = trackString('/path/to/the');
|
|
307
|
-
expect(() => {
|
|
308
|
-
path[method](segment, ['test'], {}, '/file');
|
|
309
|
-
}).to.throw;
|
|
310
|
-
});
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
if (os === 'posix') {
|
|
314
|
-
it('should properly propagate mis-matched path separator segments', function () {
|
|
315
|
-
simulateRequestScope(function () {
|
|
316
|
-
const segment = trackString(
|
|
317
|
-
'path/to/..\\invalid\\separator/file.txt'
|
|
318
|
-
);
|
|
319
|
-
const result = path[method]('/root', segment, 'end');
|
|
320
|
-
const strInfo = tracker.getData(result);
|
|
321
|
-
|
|
322
|
-
expect(strInfo?.tags).to.eql({
|
|
323
|
-
[UNTRUSTED]: [6, 42]
|
|
324
|
-
});
|
|
325
|
-
});
|
|
326
|
-
});
|
|
327
|
-
}
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
describe('join specific', function () {
|
|
331
|
-
it('tracks properly case with two relative paths', function () {
|
|
332
|
-
simulateRequestScope(function () {
|
|
333
|
-
const path1 = trackString('../foo/to/dir', {
|
|
334
|
-
tags: {
|
|
335
|
-
[UNTRUSTED]: [0, 5]
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
const path2 = trackString('../path/to/bar', {
|
|
339
|
-
tags: {
|
|
340
|
-
[UNTRUSTED]: [0, 2, 11, 13]
|
|
341
|
-
}
|
|
342
|
-
});
|
|
343
|
-
const result = path.join(path1, path2);
|
|
344
|
-
const strInfo = tracker.getData(result);
|
|
345
|
-
|
|
346
|
-
if (os === 'win32') {
|
|
347
|
-
expect(strInfo?.tags).to.eql({
|
|
348
|
-
[UNTRUSTED]: [0, 1, 3, 5, 18, 20]
|
|
349
|
-
});
|
|
350
|
-
} else {
|
|
351
|
-
expect(strInfo?.tags).to.eql({
|
|
352
|
-
[UNTRUSTED]: [0, 5, 9, 9, 18, 20]
|
|
353
|
-
});
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
});
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
describe('resolve specific', function () {
|
|
360
|
-
it('should properly move tags in case of non-absolute paths', function () {
|
|
361
|
-
simulateRequestScope(function () {
|
|
362
|
-
const workingDir = process.cwd();
|
|
363
|
-
const tagStart = 0;
|
|
364
|
-
const tagStop = 3;
|
|
365
|
-
const seg1 = trackString('my-folder', {
|
|
366
|
-
tags: {
|
|
367
|
-
[UNTRUSTED]: [tagStart, tagStop]
|
|
368
|
-
}
|
|
369
|
-
});
|
|
370
|
-
const seg2 = trackString('path/to/other/stuff.txt', {
|
|
371
|
-
tags: {
|
|
372
|
-
[UNTRUSTED]: [tagStart, tagStop]
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
const result = path.resolve(seg1, seg2);
|
|
377
|
-
const seg2Offset = workingDir.length + 1 + seg1.length + 1;
|
|
378
|
-
const strInfo = tracker.getData(result);
|
|
379
|
-
|
|
380
|
-
// Sample result for posix in GitHub windows test:
|
|
381
|
-
// '/a/node-mono/node-mono/my-folder/path/to/other/stuff.txt'
|
|
382
|
-
// Workdir is: 'D:\\a\\node-mono\\node-mono'
|
|
383
|
-
const offsetOnWindows = process.platform === 'win32' && os === 'posix' ? -2 : 0;
|
|
384
|
-
expect(strInfo.tags).to.deep.equal({
|
|
385
|
-
[UNTRUSTED]: [
|
|
386
|
-
workingDir.length + 1 + tagStart,
|
|
387
|
-
workingDir.length + 1 + tagStop,
|
|
388
|
-
seg2Offset + tagStart,
|
|
389
|
-
seg2Offset + tagStop,
|
|
390
|
-
].map(i => i + offsetOnWindows)
|
|
391
|
-
});
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
|
|
395
|
-
it('should handle adjusting ranges when multiple args', function () {
|
|
396
|
-
simulateRequestScope(function () {
|
|
397
|
-
const prefix = './path/to/something';
|
|
398
|
-
const suffixes = ['/usr', 'usr', '/root', 'file.txt'].map((s) =>
|
|
399
|
-
trackString(s)
|
|
400
|
-
);
|
|
401
|
-
const result = path.resolve(prefix, ...suffixes);
|
|
402
|
-
const strInfo = tracker.getData(result);
|
|
403
|
-
|
|
404
|
-
if (os === 'win32') {
|
|
405
|
-
if (process.platform === 'win32') {
|
|
406
|
-
// C:\\root\\file.txt
|
|
407
|
-
expect(strInfo.tags).to.deep.equal({
|
|
408
|
-
[UNTRUSTED]: [3, 6, 8, 11, 13, 15]
|
|
409
|
-
});
|
|
410
|
-
} else {
|
|
411
|
-
// \\root\\file.txt
|
|
412
|
-
expect(strInfo.tags).to.deep.equal({
|
|
413
|
-
[UNTRUSTED]: [1, 4, 6, 9, 11, 13]
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
} else {
|
|
417
|
-
expect(strInfo.tags).to.deep.equal({
|
|
418
|
-
[UNTRUSTED]: [0, 4, 6, 9, 11, 13]
|
|
419
|
-
});
|
|
420
|
-
}
|
|
421
|
-
});
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
it('should handle adjusting ranges when fully overwritten', function () {
|
|
425
|
-
simulateRequestScope(function () {
|
|
426
|
-
const prefix = '/path/to/something';
|
|
427
|
-
const suffix = trackString('./../../../../etc/shadow.txt');
|
|
428
|
-
|
|
429
|
-
const result = path.resolve(prefix, suffix);
|
|
430
|
-
const strInfo = tracker.getData(result);
|
|
431
|
-
|
|
432
|
-
if (os === 'win32') {
|
|
433
|
-
if (process.platform === 'win32') {
|
|
434
|
-
// C:\\etc\\shadow.txt
|
|
435
|
-
expect(strInfo.tags).to.deep.equal({
|
|
436
|
-
[UNTRUSTED]: [3, 5, 7, 12, 14, 16]
|
|
437
|
-
});
|
|
438
|
-
} else {
|
|
439
|
-
// \\etc\\shadow.txt
|
|
440
|
-
expect(strInfo.tags).to.deep.equal({
|
|
441
|
-
[UNTRUSTED]: [1, 3, 5, 10, 12, 14]
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
} else {
|
|
445
|
-
expect(strInfo.tags).to.deep.equal({
|
|
446
|
-
[UNTRUSTED]: [0, 10, 12, 14]
|
|
447
|
-
});
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
});
|
|
451
|
-
|
|
452
|
-
if (os === 'win32') {
|
|
453
|
-
it('should handle adjusting ranges on windows absolute paths', function () {
|
|
454
|
-
simulateRequestScope(function () {
|
|
455
|
-
const prefix = 'C:\\WINDOWS/system32';
|
|
456
|
-
const suffix = trackString('win.ini');
|
|
457
|
-
|
|
458
|
-
const result = path.resolve(prefix, suffix);
|
|
459
|
-
const strInfo = tracker.getData(result);
|
|
460
|
-
|
|
461
|
-
expect(strInfo.tags).to.deep.equal({
|
|
462
|
-
[UNTRUSTED]: [20, 22, 24, 26]
|
|
463
|
-
});
|
|
464
|
-
});
|
|
465
|
-
});
|
|
466
|
-
|
|
467
|
-
it('should handle paths with unicode chars and spaces', function () {
|
|
468
|
-
simulateRequestScope(function () {
|
|
469
|
-
const prefix = 'C:\\WINDOWS\\Users\\Ивайло';
|
|
470
|
-
const suffix = trackString('Моите Документи');
|
|
471
|
-
|
|
472
|
-
const result = path.resolve(prefix, suffix);
|
|
473
|
-
const strInfo = tracker.getData(result);
|
|
474
|
-
|
|
475
|
-
expect(strInfo.tags).to.deep.equal({
|
|
476
|
-
[UNTRUSTED]: [24, 38]
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
});
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
});
|
|
483
|
-
});
|
|
484
|
-
});
|
|
485
|
-
|
|
@@ -1,176 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {
|
|
4
|
-
DataflowTag: { UNTRUSTED, STRING_TYPE_CHECKED, CUSTOM_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 path normalize', function () {
|
|
11
|
-
let core, tracker, createPropagationEvent, trackString, simulateRequestScope;
|
|
12
|
-
|
|
13
|
-
beforeEach(function () {
|
|
14
|
-
({ core, simulateRequestScope, trackString } = initAssessFixture());
|
|
15
|
-
tracker = core.assess.dataflow.tracker;
|
|
16
|
-
createPropagationEvent = sinon.spy(
|
|
17
|
-
core.assess.eventFactory,
|
|
18
|
-
'createPropagationEvent'
|
|
19
|
-
);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
['posix', 'win32'].forEach((os) => {
|
|
23
|
-
describe(os, function () {
|
|
24
|
-
let path;
|
|
25
|
-
|
|
26
|
-
beforeEach(function () {
|
|
27
|
-
path = require('path')[os];
|
|
28
|
-
|
|
29
|
-
core.depHooks.resolve.yields(path);
|
|
30
|
-
const normalizeInstr = require('./normalize')(core);
|
|
31
|
-
normalizeInstr.install();
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it('should ignore empty string', function () {
|
|
35
|
-
simulateRequestScope(function () {
|
|
36
|
-
const myPath = trackString('');
|
|
37
|
-
|
|
38
|
-
const file = path.normalize(myPath);
|
|
39
|
-
const strInfo = tracker.getData(file);
|
|
40
|
-
|
|
41
|
-
expect(strInfo).to.be.null;
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
it('will not propagate if there is no assess policy in request context', function () {
|
|
46
|
-
simulateRequestScope(function () {
|
|
47
|
-
const myPath = trackString('/path');
|
|
48
|
-
|
|
49
|
-
const result = path.normalize(myPath);
|
|
50
|
-
|
|
51
|
-
expect(tracker.getData(result)).to.be.null;
|
|
52
|
-
}, { assess: { policy: null } });
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('will not propagate if there instrumentation is locked', function () {
|
|
56
|
-
simulateRequestScope(function () {
|
|
57
|
-
core.scopes.instrumentation.run({ lock: true }, function () {
|
|
58
|
-
const myPath = trackString('/path');
|
|
59
|
-
|
|
60
|
-
const result = path.normalize(myPath);
|
|
61
|
-
|
|
62
|
-
expect(tracker.getData(result)).to.be.null;
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('will not propagate if the argument is not tracked', function () {
|
|
68
|
-
simulateRequestScope(function () {
|
|
69
|
-
const myPath = '/path';
|
|
70
|
-
|
|
71
|
-
path.normalize(myPath);
|
|
72
|
-
|
|
73
|
-
expect(createPropagationEvent).to.not.have.been.called;
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
it('will not propagate if there no event created', function () {
|
|
78
|
-
simulateRequestScope(function () {
|
|
79
|
-
core.config.assess.max_propagation_events = 0;
|
|
80
|
-
const myPath = trackString('/path');
|
|
81
|
-
|
|
82
|
-
const result = path.normalize(myPath);
|
|
83
|
-
|
|
84
|
-
expect(tracker.getData(result)).to.be.null;
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
it('Support test/edge case (ported from v4)', function () {
|
|
89
|
-
simulateRequestScope(function () {
|
|
90
|
-
const extern = trackString('.//public/../private/private.txt');
|
|
91
|
-
|
|
92
|
-
const result = path.normalize(extern);
|
|
93
|
-
const strInfo = tracker.getData(result);
|
|
94
|
-
|
|
95
|
-
if (os === 'win32') {
|
|
96
|
-
// win32 transforms the '/' to '\' so we should untrack it
|
|
97
|
-
expect(strInfo.tags).to.deep.equal({
|
|
98
|
-
[UNTRUSTED]: [0, 6, 8, 14, 16, 18],
|
|
99
|
-
});
|
|
100
|
-
} else {
|
|
101
|
-
expect(strInfo.tags).to.deep.equal({
|
|
102
|
-
[UNTRUSTED]: [0, 14, 16, 18],
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('should track entire path if entire string was tracked before normalizing', function () {
|
|
109
|
-
simulateRequestScope(function () {
|
|
110
|
-
const myPath = trackString('/path/./to/replaced/../dir/./file.txt');
|
|
111
|
-
|
|
112
|
-
const normPath = path.normalize(myPath);
|
|
113
|
-
const strInfo = tracker.getData(normPath);
|
|
114
|
-
|
|
115
|
-
if (os === 'win32') {
|
|
116
|
-
// Transformation from / to \ separators which are untracked
|
|
117
|
-
expect(strInfo.tags).to.deep.equal({
|
|
118
|
-
[UNTRUSTED]: [1, 4, 6, 7, 9, 11, 13, 16, 18, 20],
|
|
119
|
-
});
|
|
120
|
-
} else {
|
|
121
|
-
expect(strInfo.tags).to.deep.equal({
|
|
122
|
-
[UNTRUSTED]: [0, 16, 18, 20],
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
it('should track parts of a path', function () {
|
|
129
|
-
simulateRequestScope(function () {
|
|
130
|
-
const myPath = trackString('/path/to/the/file/../bogus/..', {
|
|
131
|
-
tags: {
|
|
132
|
-
[UNTRUSTED]: [1, 4, 13, 16],
|
|
133
|
-
[CUSTOM_ENCODED]: [3, 20],
|
|
134
|
-
[STRING_TYPE_CHECKED]: [10, 12],
|
|
135
|
-
},
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
const normPath = path.normalize(myPath);
|
|
139
|
-
const strInfo = tracker.getData(normPath);
|
|
140
|
-
if (os === 'win32') {
|
|
141
|
-
// Transformation from / to \ separators which are untracked
|
|
142
|
-
expect(strInfo.tags).to.deep.equal({
|
|
143
|
-
[UNTRUSTED]: [1, 4],
|
|
144
|
-
[CUSTOM_ENCODED]: [3, 4, 6, 7, 9, 11],
|
|
145
|
-
[STRING_TYPE_CHECKED]: [10, 11],
|
|
146
|
-
});
|
|
147
|
-
} else {
|
|
148
|
-
expect(strInfo.tags).to.deep.equal({
|
|
149
|
-
[UNTRUSTED]: [1, 4],
|
|
150
|
-
[CUSTOM_ENCODED]: [3, 11],
|
|
151
|
-
[STRING_TYPE_CHECKED]: [10, 11],
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
if (os === 'win32') {
|
|
158
|
-
it('should track parts of windows absolute path', function () {
|
|
159
|
-
simulateRequestScope(function () {
|
|
160
|
-
const myPath = trackString('C:\\path\\..\\unexpected.txt', {
|
|
161
|
-
tags: {
|
|
162
|
-
[UNTRUSTED]: [7, 24],
|
|
163
|
-
},
|
|
164
|
-
});
|
|
165
|
-
const normPath = path.normalize(myPath);
|
|
166
|
-
const strInfo = tracker.getData(normPath);
|
|
167
|
-
|
|
168
|
-
expect(strInfo.tags).to.deep.equal({
|
|
169
|
-
[UNTRUSTED]: [2, 12, 14, 16],
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
});
|