@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.
- package/lib/crypto-analysis/install/crypto.js +1 -1
- package/lib/dataflow/propagation/install/JSON/parse-fn.js +1 -1
- package/lib/dataflow/propagation/install/JSON/parse.js +3 -2
- package/lib/dataflow/propagation/install/JSON/parse.test.js +2 -2
- package/lib/dataflow/propagation/install/JSON/stringify.js +11 -10
- package/lib/dataflow/propagation/install/JSON/stringify.test.js +3 -3
- package/lib/dataflow/propagation/install/array-prototype-join.js +4 -3
- package/lib/dataflow/propagation/install/array-prototype-join.test.js +3 -3
- package/lib/dataflow/propagation/install/buffer.js +2 -3
- package/lib/dataflow/propagation/install/contrast-methods/tag.test.js +2 -2
- package/lib/dataflow/propagation/install/decode-uri-component.js +5 -8
- package/lib/dataflow/propagation/install/decode-uri-component.test.js +1 -1
- package/lib/dataflow/propagation/install/ejs/escape-xml.js +6 -9
- package/lib/dataflow/propagation/install/ejs/escape-xml.test.js +2 -2
- package/lib/dataflow/propagation/install/ejs/template.js +2 -2
- package/lib/dataflow/propagation/install/encode-uri.js +4 -6
- package/lib/dataflow/propagation/install/encode-uri.test.js +2 -2
- package/lib/dataflow/propagation/install/escape-html.js +5 -8
- package/lib/dataflow/propagation/install/escape-html.test.js +3 -3
- package/lib/dataflow/propagation/install/escape.js +5 -8
- package/lib/dataflow/propagation/install/escape.test.js +2 -2
- package/lib/dataflow/propagation/install/fastify-send.js +3 -5
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +6 -9
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.test.js +1 -1
- package/lib/dataflow/propagation/install/joi/boolean.js +50 -52
- package/lib/dataflow/propagation/install/joi/expression.js +3 -10
- package/lib/dataflow/propagation/install/joi/index.js +98 -101
- package/lib/dataflow/propagation/install/joi/keys.js +10 -5
- package/lib/dataflow/propagation/install/joi/number.js +50 -52
- package/lib/dataflow/propagation/install/joi/string-schema.js +9 -14
- package/lib/dataflow/propagation/install/joi/utils.js +7 -4
- package/lib/dataflow/propagation/install/joi/values.js +5 -7
- package/lib/dataflow/propagation/install/mongoose/schema-map.js +5 -4
- package/lib/dataflow/propagation/install/mongoose/schema-map.test.js +4 -4
- package/lib/dataflow/propagation/install/mongoose/schema-mixed.js +5 -4
- package/lib/dataflow/propagation/install/mongoose/schema-mixed.test.js +4 -5
- package/lib/dataflow/propagation/install/mongoose/schema-string.js +99 -5
- package/lib/dataflow/propagation/install/mongoose/schema-string.test.js +41 -2
- package/lib/dataflow/propagation/install/mustache-escape.js +5 -8
- package/lib/dataflow/propagation/install/mustache-escape.test.js +2 -2
- package/lib/dataflow/propagation/install/mysql-connection-escape.js +5 -8
- package/lib/dataflow/propagation/install/mysql-connection-escape.test.js +2 -2
- package/lib/dataflow/propagation/install/parse-int.js +3 -3
- package/lib/dataflow/propagation/install/path/basename.js +7 -12
- package/lib/dataflow/propagation/install/path/basename.test.js +2 -2
- package/lib/dataflow/propagation/install/path/common.js +2 -2
- package/lib/dataflow/propagation/install/path/dirname.js +5 -10
- package/lib/dataflow/propagation/install/path/dirname.test.js +2 -2
- package/lib/dataflow/propagation/install/path/extname.js +6 -11
- package/lib/dataflow/propagation/install/path/extname.test.js +2 -2
- package/lib/dataflow/propagation/install/path/format.js +7 -13
- package/lib/dataflow/propagation/install/path/format.test.js +2 -2
- package/lib/dataflow/propagation/install/path/join-and-resolve.js +7 -12
- package/lib/dataflow/propagation/install/path/join-and-resolve.test.js +2 -2
- package/lib/dataflow/propagation/install/path/normalize.js +4 -11
- package/lib/dataflow/propagation/install/path/normalize.test.js +2 -2
- package/lib/dataflow/propagation/install/path/parse.js +3 -8
- package/lib/dataflow/propagation/install/path/parse.test.js +2 -2
- package/lib/dataflow/propagation/install/path/relative.js +5 -11
- package/lib/dataflow/propagation/install/path/relative.test.js +2 -2
- package/lib/dataflow/propagation/install/path/toNamespacedPath.js +5 -11
- package/lib/dataflow/propagation/install/path/toNamespacedPath.test.js +2 -2
- package/lib/dataflow/propagation/install/pug/index.js +8 -3
- package/lib/dataflow/propagation/install/pug-runtime-escape.js +5 -8
- package/lib/dataflow/propagation/install/pug-runtime-escape.test.js +1 -1
- package/lib/dataflow/propagation/install/querystring/escape.js +3 -3
- package/lib/dataflow/propagation/install/querystring/parse.js +7 -11
- package/lib/dataflow/propagation/install/querystring/stringify.js +3 -3
- package/lib/dataflow/propagation/install/reg-exp-prototype-exec.js +4 -3
- package/lib/dataflow/propagation/install/reg-exp-prototype-exec.test.js +5 -3
- package/lib/dataflow/propagation/install/send.js +5 -10
- package/lib/dataflow/propagation/install/sequelize/query-generator.js +3 -4
- package/lib/dataflow/propagation/install/sequelize/sql-string.js +8 -12
- package/lib/dataflow/propagation/install/sequelize/sql-string.test.js +2 -13
- package/lib/dataflow/propagation/install/sql-template-strings.js +3 -5
- package/lib/dataflow/propagation/install/sql-template-strings.test.js +2 -2
- package/lib/dataflow/propagation/install/string/concat.js +2 -1
- package/lib/dataflow/propagation/install/string/concat.test.js +15 -2
- package/lib/dataflow/propagation/install/string/format-methods.js +4 -2
- package/lib/dataflow/propagation/install/string/format-methods.test.js +15 -2
- package/lib/dataflow/propagation/install/string/html-methods.js +1 -1
- package/lib/dataflow/propagation/install/string/html-methods.test.js +15 -2
- package/lib/dataflow/propagation/install/string/index.js +2 -2
- package/lib/dataflow/propagation/install/string/match-all.js +2 -1
- package/lib/dataflow/propagation/install/string/match-all.test.js +13 -0
- package/lib/dataflow/propagation/install/string/match.js +11 -10
- package/lib/dataflow/propagation/install/string/match.test.js +13 -0
- package/lib/dataflow/propagation/install/string/replace.js +15 -9
- package/lib/dataflow/propagation/install/string/replace.test.js +13 -0
- package/lib/dataflow/propagation/install/string/slice.js +2 -1
- package/lib/dataflow/propagation/install/string/slice.test.js +13 -0
- package/lib/dataflow/propagation/install/string/split.js +2 -1
- package/lib/dataflow/propagation/install/string/split.test.js +13 -0
- package/lib/dataflow/propagation/install/string/substring.js +2 -1
- package/lib/dataflow/propagation/install/string/substring.test.js +13 -0
- package/lib/dataflow/propagation/install/string/trim.js +4 -1
- package/lib/dataflow/propagation/install/string/trim.test.js +13 -0
- package/lib/dataflow/propagation/install/unescape.js +5 -8
- package/lib/dataflow/propagation/install/unescape.test.js +2 -2
- package/lib/dataflow/propagation/install/url/domain-parsers.js +4 -5
- package/lib/dataflow/propagation/install/url/domain-parsers.test.js +2 -2
- package/lib/dataflow/propagation/install/url/parse.js +3 -2
- package/lib/dataflow/propagation/install/url/parse.test.js +2 -2
- package/lib/dataflow/propagation/install/url/searchParams.js +5 -5
- package/lib/dataflow/propagation/install/url/searchParams.test.js +2 -2
- package/lib/dataflow/propagation/install/url/url.js +6 -3
- package/lib/dataflow/propagation/install/url/url.test.js +2 -2
- package/lib/dataflow/propagation/install/util-format.js +7 -6
- package/lib/dataflow/propagation/install/util-format.test.js +2 -2
- package/lib/dataflow/propagation/install/validator/hooks.js +7 -2
- package/lib/dataflow/sinks/install/child-process.js +1 -1
- package/lib/dataflow/sinks/install/child-process.test.js +1 -1
- package/lib/dataflow/sinks/install/fs.js +1 -1
- package/lib/dataflow/sinks/install/fs.test.js +1 -1
- package/lib/dataflow/sinks/install/function.js +1 -1
- package/lib/dataflow/sinks/install/http/request.js +2 -1
- package/lib/dataflow/sinks/install/http/request.test.js +1 -1
- package/lib/dataflow/sinks/install/http/server-response.test.js +3 -5
- package/lib/dataflow/sinks/install/restify.js +1 -1
- package/lib/dataflow/sinks/install/vm.js +4 -2
- package/lib/dataflow/sinks/install/vm.test.js +1 -1
- package/lib/dataflow/sources/handler.js +5 -2
- package/lib/dataflow/sources/install/body-parser1.test.js +4 -4
- package/lib/dataflow/sources/install/busboy.js +8 -3
- package/lib/dataflow/sources/install/busboy.test.js +2 -2
- package/lib/dataflow/sources/install/cookie-parser1.test.js +2 -2
- package/lib/dataflow/sources/install/express/params.js +14 -11
- package/lib/dataflow/sources/install/express/params.test.js +5 -7
- package/lib/dataflow/sources/install/express/parsedUrl.js +3 -2
- package/lib/dataflow/sources/install/fastify/fastify.js +7 -6
- package/lib/dataflow/sources/install/fastify/fastify.test.js +2 -2
- package/lib/dataflow/sources/install/formidable1.js +7 -6
- package/lib/dataflow/sources/install/formidable1.test.js +2 -2
- package/lib/dataflow/sources/install/hapi/hapi.js +8 -10
- package/lib/dataflow/sources/install/hapi/hapi.test.js +0 -1
- package/lib/dataflow/sources/install/http.js +20 -16
- package/lib/dataflow/sources/install/http.test.js +28 -34
- package/lib/dataflow/sources/install/koa/koa-bodyparsers.js +7 -7
- package/lib/dataflow/sources/install/koa/koa-bodyparsers.test.js +3 -4
- package/lib/dataflow/sources/install/koa/koa-multer.js +8 -4
- package/lib/dataflow/sources/install/koa/koa-routers.js +7 -6
- package/lib/dataflow/sources/install/koa/koa-routers.test.js +2 -2
- package/lib/dataflow/sources/install/koa/koa2.js +7 -3
- package/lib/dataflow/sources/install/koa/koa2.test.js +1 -1
- package/lib/dataflow/sources/install/multer1.js +6 -2
- package/lib/dataflow/sources/install/qs6.js +1 -1
- package/lib/dataflow/sources/install/querystring.js +1 -1
- package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.js +1 -4
- package/lib/dataflow/sources/install/restify/fieldedTextBodyParser.test.js +6 -8
- package/lib/dataflow/sources/install/restify/jsonBodyParser.js +0 -1
- package/lib/dataflow/sources/install/restify/jsonBodyParser.test.js +4 -8
- package/lib/dataflow/sources/install/restify/router.test.js +2 -2
- package/lib/dataflow/tag-utils.js +1 -1
- package/lib/dataflow/tracker.js +1 -1
- package/lib/dataflow/utils/is-safe-content-type.js +3 -2
- package/lib/event-factory.js +4 -4
- package/lib/get-policy.js +2 -2
- package/lib/index.js +18 -7
- package/lib/index.test.js +4 -0
- package/lib/make-source-context.js +37 -28
- package/lib/make-source-context.test.js +7 -7
- package/lib/response-scanning/handlers/index.js +7 -5
- package/lib/response-scanning/handlers/utils.js +11 -8
- package/lib/response-scanning/install/http.js +1 -1
- package/lib/sampler.js +136 -0
- package/lib/sampler.test.js +296 -0
- package/lib/session-configuration/install/express-session.js +1 -1
- package/lib/session-configuration/install/fastify-cookie.js +1 -1
- 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
|
-
|
|
20
|
-
} = require('
|
|
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] || !
|
|
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
|
-
|
|
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] || !
|
|
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] || !
|
|
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 {
|
|
19
|
-
const {
|
|
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] || !
|
|
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] || !
|
|
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] =
|
|
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 {
|
|
19
|
-
const {
|
|
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]) || !
|
|
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]
|
|
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 (
|
|
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
|
|
|
@@ -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;
|
|
@@ -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 () {
|
|
@@ -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 (
|
|
88
|
+
if (RegExpPrototypeExec.call(trusted, file)) {
|
|
88
89
|
return true;
|
|
89
90
|
}
|
|
90
91
|
}
|
|
@@ -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
|
-
}
|
|
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
|
-
|
|
31
|
-
|
|
30
|
+
primordials: {
|
|
31
|
+
ArrayPrototypeJoin,
|
|
32
|
+
StringPrototypeSplit,
|
|
33
|
+
},
|
|
32
34
|
traverseValues,
|
|
33
35
|
} = require('@contrast/common');
|
|
34
36
|
const { InstrumentationType: { RULE } } = require('../../../constants');
|