@contrast/assess 1.10.0 → 1.12.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/dataflow/index.js +1 -2
- package/lib/dataflow/propagation/common.js +1 -1
- package/lib/dataflow/propagation/index.js +2 -1
- package/lib/dataflow/propagation/install/JSON/index.js +1 -1
- package/lib/dataflow/propagation/install/JSON/parse-fn.js +1 -1
- package/lib/dataflow/propagation/install/JSON/parse.js +3 -5
- package/lib/dataflow/propagation/install/JSON/stringify.js +3 -2
- package/lib/dataflow/propagation/install/array-prototype-join.js +3 -2
- package/lib/dataflow/propagation/install/buffer.js +3 -5
- package/lib/dataflow/propagation/install/contrast-methods/add.js +3 -2
- package/lib/dataflow/propagation/install/contrast-methods/index.js +1 -1
- package/lib/dataflow/propagation/install/contrast-methods/number.js +1 -1
- package/lib/dataflow/propagation/install/contrast-methods/string.js +3 -5
- package/lib/dataflow/propagation/install/contrast-methods/tag.js +3 -5
- package/lib/dataflow/propagation/install/decode-uri-component.js +3 -2
- package/lib/dataflow/propagation/install/ejs/escape-xml.js +3 -2
- package/lib/dataflow/propagation/install/ejs/index.js +1 -1
- package/lib/dataflow/propagation/install/encode-uri-component.js +3 -2
- package/lib/dataflow/propagation/install/escape-html.js +3 -2
- package/lib/dataflow/propagation/install/escape.js +3 -2
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +3 -2
- package/lib/dataflow/propagation/install/isnumeric-0.js +1 -1
- package/lib/dataflow/propagation/install/mongoose/common.js +20 -0
- package/lib/dataflow/propagation/install/mongoose/index.js +5 -9
- package/lib/dataflow/propagation/install/mongoose/schema-map.js +149 -0
- package/lib/dataflow/propagation/install/mongoose/schema-mixed.js +162 -0
- package/lib/dataflow/propagation/install/mongoose/schema-string.js +91 -39
- package/lib/dataflow/propagation/install/mysql-connection-escape.js +3 -2
- package/lib/dataflow/propagation/install/parse-int.js +1 -1
- package/lib/dataflow/propagation/install/path/basename.js +3 -5
- package/lib/dataflow/propagation/install/path/common.js +1 -1
- package/lib/dataflow/propagation/install/path/index.js +1 -1
- package/lib/dataflow/propagation/install/path/join-and-resolve.js +3 -5
- package/lib/dataflow/propagation/install/path/normalize.js +3 -5
- package/lib/dataflow/propagation/install/pug/index.js +1 -1
- package/lib/dataflow/propagation/install/pug-runtime-escape.js +3 -2
- package/lib/dataflow/propagation/install/querystring/index.js +1 -1
- package/lib/dataflow/propagation/install/querystring/parse.js +3 -2
- package/lib/dataflow/propagation/install/reg-exp-prototype-exec.js +180 -0
- package/lib/dataflow/propagation/install/sequelize.js +3 -5
- package/lib/dataflow/propagation/install/sql-template-strings.js +3 -2
- package/lib/dataflow/propagation/install/string/concat.js +3 -2
- package/lib/dataflow/propagation/install/string/format-methods.js +3 -2
- package/lib/dataflow/propagation/install/string/html-methods.js +3 -2
- package/lib/dataflow/propagation/install/string/index.js +66 -1
- package/lib/dataflow/propagation/install/string/match-all.js +236 -0
- package/lib/dataflow/propagation/install/string/match.js +83 -37
- package/lib/dataflow/propagation/install/string/replace.js +4 -3
- package/lib/dataflow/propagation/install/string/slice.js +3 -2
- package/lib/dataflow/propagation/install/string/split.js +3 -2
- package/lib/dataflow/propagation/install/string/substring.js +3 -2
- package/lib/dataflow/propagation/install/string/trim.js +3 -2
- package/lib/dataflow/propagation/install/unescape.js +3 -2
- package/lib/dataflow/propagation/install/url/domain-parsers.js +3 -2
- package/lib/dataflow/propagation/install/url/index.js +3 -1
- package/lib/dataflow/propagation/install/url/parse.js +132 -0
- package/lib/dataflow/propagation/install/url/searchParams.js +140 -0
- package/lib/dataflow/propagation/install/url/url.js +11 -53
- package/lib/dataflow/propagation/install/validator/hooks.js +3 -2
- package/lib/dataflow/propagation/install/validator/index.js +1 -1
- package/lib/dataflow/propagation/install/validator/methods.js +1 -1
- package/lib/dataflow/sinks/common.js +1 -1
- package/lib/dataflow/sinks/index.js +1 -1
- package/lib/dataflow/sinks/install/child-process.js +2 -2
- package/lib/dataflow/sinks/install/eval.js +2 -2
- package/lib/dataflow/sinks/install/express/index.js +1 -1
- package/lib/dataflow/sinks/install/express/unvalidated-redirect.js +3 -3
- package/lib/dataflow/sinks/install/fastify/index.js +1 -1
- package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +2 -2
- package/lib/dataflow/sinks/install/fs.js +2 -2
- package/lib/dataflow/sinks/install/function.js +2 -2
- package/lib/dataflow/sinks/install/http/index.js +1 -1
- package/lib/dataflow/sinks/install/http/request.js +2 -2
- package/lib/dataflow/sinks/install/http/server-response.js +2 -2
- package/lib/dataflow/sinks/install/koa/index.js +1 -1
- package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +2 -2
- package/lib/dataflow/sinks/install/marsdb.js +2 -2
- package/lib/dataflow/sinks/install/mongodb.js +33 -26
- package/lib/dataflow/sinks/install/mssql.js +2 -2
- package/lib/dataflow/sinks/install/mysql.js +3 -3
- package/lib/dataflow/sinks/install/postgres.js +2 -2
- package/lib/dataflow/sinks/install/sequelize.js +2 -2
- package/lib/dataflow/sinks/install/sqlite3.js +2 -2
- package/lib/dataflow/sinks/install/vm.js +2 -2
- package/lib/dataflow/sources/common.js +1 -1
- package/lib/dataflow/sources/handler.js +3 -3
- package/lib/dataflow/sources/index.js +1 -1
- package/lib/dataflow/sources/install/body-parser1.js +1 -1
- package/lib/dataflow/sources/install/busboy1.js +1 -1
- package/lib/dataflow/sources/install/cookie-parser1.js +1 -1
- package/lib/dataflow/sources/install/express/index.js +1 -1
- package/lib/dataflow/sources/install/express/params.js +1 -1
- package/lib/dataflow/sources/install/express/parsedUrl.js +1 -1
- package/lib/dataflow/sources/install/fastify/fastify.js +1 -1
- package/lib/dataflow/sources/install/fastify/index.js +1 -1
- package/lib/dataflow/sources/install/formidable1.js +1 -1
- package/lib/dataflow/sources/install/http.js +2 -2
- package/lib/dataflow/sources/install/koa/index.js +1 -1
- package/lib/dataflow/sources/install/koa/koa-bodyparsers.js +1 -1
- package/lib/dataflow/sources/install/koa/koa-routers.js +1 -1
- package/lib/dataflow/sources/install/koa/koa2.js +1 -1
- package/lib/dataflow/sources/install/qs6.js +1 -1
- package/lib/dataflow/sources/install/querystring.js +1 -1
- package/lib/dataflow/tag-utils.js +1 -1
- package/lib/dataflow/tracker.js +2 -6
- package/lib/dataflow/utils/is-safe-content-type.js +1 -1
- package/lib/dataflow/utils/is-vulnerable.js +1 -1
- package/lib/{dataflow/event-factory.js → event-factory.js} +58 -2
- package/lib/index.js +4 -2
- package/lib/response-scanning/handlers/index.js +36 -30
- package/lib/response-scanning/handlers/utils.js +1 -1
- package/lib/response-scanning/index.js +1 -1
- package/lib/response-scanning/install/http.js +3 -3
- package/lib/session-configuration/common.js +19 -0
- package/lib/session-configuration/handlers.js +86 -0
- package/lib/session-configuration/index.js +6 -9
- package/lib/session-configuration/install/express-session.js +131 -0
- package/package.json +3 -3
- package/lib/session-configuration/install/http.js +0 -79
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -25,7 +25,8 @@ module.exports = function(core) {
|
|
|
25
25
|
scopes: { sources, instrumentation },
|
|
26
26
|
patcher,
|
|
27
27
|
assess: {
|
|
28
|
-
|
|
28
|
+
eventFactory: { createPropagationEvent },
|
|
29
|
+
dataflow: { tracker }
|
|
29
30
|
}
|
|
30
31
|
} = core;
|
|
31
32
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -28,7 +28,8 @@ module.exports = function(core) {
|
|
|
28
28
|
scopes: { sources, instrumentation },
|
|
29
29
|
patcher,
|
|
30
30
|
assess: {
|
|
31
|
-
|
|
31
|
+
eventFactory: { createPropagationEvent },
|
|
32
|
+
dataflow: { tracker }
|
|
32
33
|
}
|
|
33
34
|
} = core;
|
|
34
35
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -26,7 +26,8 @@ module.exports = function(core) {
|
|
|
26
26
|
patcher,
|
|
27
27
|
depHooks,
|
|
28
28
|
assess: {
|
|
29
|
-
|
|
29
|
+
eventFactory: { createPropagationEvent },
|
|
30
|
+
dataflow: { tracker }
|
|
30
31
|
}
|
|
31
32
|
} = core;
|
|
32
33
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -28,6 +28,8 @@ module.exports = function(core) {
|
|
|
28
28
|
};
|
|
29
29
|
|
|
30
30
|
require('./domain-parsers')(core);
|
|
31
|
+
require('./parse')(core);
|
|
32
|
+
require('./searchParams')(core);
|
|
31
33
|
require('./url')(core);
|
|
32
34
|
|
|
33
35
|
return urlInstrumentation;
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
|
+
* Contact: support@contrastsecurity.com
|
|
4
|
+
* License: Commercial
|
|
5
|
+
|
|
6
|
+
* NOTICE: This Software and the patented inventions embodied within may only be
|
|
7
|
+
* used as part of Contrast Security’s commercial offerings. Even though it is
|
|
8
|
+
* made available through public repositories, use of this Software is subject to
|
|
9
|
+
* the applicable End User Licensing Agreement found at
|
|
10
|
+
* https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
|
|
11
|
+
* between Contrast Security and the End User. The Software may not be reverse
|
|
12
|
+
* engineered, modified, repackaged, sold, redistributed or otherwise used in a
|
|
13
|
+
* way not consistent with the End User License Agreement.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
const { patchType } = require('../../common');
|
|
19
|
+
const { inspect } = require('@contrast/common');
|
|
20
|
+
|
|
21
|
+
module.exports = function(core) {
|
|
22
|
+
const {
|
|
23
|
+
scopes: { sources, instrumentation },
|
|
24
|
+
patcher,
|
|
25
|
+
depHooks,
|
|
26
|
+
assess: {
|
|
27
|
+
eventFactory: { createPropagationEvent },
|
|
28
|
+
dataflow: { tracker }
|
|
29
|
+
}
|
|
30
|
+
} = core;
|
|
31
|
+
|
|
32
|
+
const keys = [
|
|
33
|
+
'href',
|
|
34
|
+
[
|
|
35
|
+
'protocol',
|
|
36
|
+
'auth',
|
|
37
|
+
'host',
|
|
38
|
+
[
|
|
39
|
+
'hostname',
|
|
40
|
+
'port'
|
|
41
|
+
],
|
|
42
|
+
'path',
|
|
43
|
+
[
|
|
44
|
+
'pathname',
|
|
45
|
+
'search',
|
|
46
|
+
[
|
|
47
|
+
'query'
|
|
48
|
+
]
|
|
49
|
+
],
|
|
50
|
+
'hash'
|
|
51
|
+
]
|
|
52
|
+
];
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
return core.assess.dataflow.propagation.urlInstrumentation.parse = {
|
|
56
|
+
install() {
|
|
57
|
+
depHooks.resolve({ name: 'url' }, (url) => {
|
|
58
|
+
|
|
59
|
+
const name = 'url.parse';
|
|
60
|
+
|
|
61
|
+
patcher.patch(url, 'parse', {
|
|
62
|
+
name,
|
|
63
|
+
patchType,
|
|
64
|
+
post(data) {
|
|
65
|
+
const { args, result, hooked, orig } = data;
|
|
66
|
+
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
|
|
67
|
+
|
|
68
|
+
const url = args[0];
|
|
69
|
+
const argInfo = tracker.getData(url);
|
|
70
|
+
|
|
71
|
+
if (!argInfo) return;
|
|
72
|
+
|
|
73
|
+
const traverse = function(href, url, keys, idx = 0) {
|
|
74
|
+
let substr = href;
|
|
75
|
+
keys.forEach((key) => {
|
|
76
|
+
if (typeof key === 'string') {
|
|
77
|
+
const part = result[key];
|
|
78
|
+
if (part) {
|
|
79
|
+
const index = href.indexOf(part, idx - 1);
|
|
80
|
+
substr = href.substring(index, index + part.length);
|
|
81
|
+
idx += part.length;
|
|
82
|
+
|
|
83
|
+
const partInfo = tracker.getData(substr);
|
|
84
|
+
if (!partInfo) return;
|
|
85
|
+
|
|
86
|
+
const event = createPropagationEvent({
|
|
87
|
+
name,
|
|
88
|
+
moduleName: 'url',
|
|
89
|
+
methodName: 'parse',
|
|
90
|
+
context: `url.parse('${argInfo.value}')`,
|
|
91
|
+
object: {
|
|
92
|
+
value: 'url',
|
|
93
|
+
tracked: false
|
|
94
|
+
},
|
|
95
|
+
result: {
|
|
96
|
+
value: inspect(result),
|
|
97
|
+
tracked: true
|
|
98
|
+
},
|
|
99
|
+
args: [{ value: partInfo.value, tracked: true }],
|
|
100
|
+
tags: partInfo.tags,
|
|
101
|
+
history: [partInfo],
|
|
102
|
+
source: 'P',
|
|
103
|
+
target: 'R',
|
|
104
|
+
stacktraceOpts: {
|
|
105
|
+
constructorOpt: hooked,
|
|
106
|
+
prependFrames: [orig]
|
|
107
|
+
},
|
|
108
|
+
});
|
|
109
|
+
if (!event) return;
|
|
110
|
+
|
|
111
|
+
if (partInfo) {
|
|
112
|
+
Object.assign(partInfo, event);
|
|
113
|
+
}
|
|
114
|
+
const { extern } = partInfo || tracker.track(part, event);
|
|
115
|
+
|
|
116
|
+
if (extern) {
|
|
117
|
+
result[key] = extern;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
} else {
|
|
121
|
+
traverse(substr, url, key, 0);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
traverse(url, result, keys, 0);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
};
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
|
+
* Contact: support@contrastsecurity.com
|
|
4
|
+
* License: Commercial
|
|
5
|
+
|
|
6
|
+
* NOTICE: This Software and the patented inventions embodied within may only be
|
|
7
|
+
* used as part of Contrast Security’s commercial offerings. Even though it is
|
|
8
|
+
* made available through public repositories, use of this Software is subject to
|
|
9
|
+
* the applicable End User Licensing Agreement found at
|
|
10
|
+
* https://www.contrastsecurity.com/enduser-terms-0317a or as otherwise agreed
|
|
11
|
+
* between Contrast Security and the End User. The Software may not be reverse
|
|
12
|
+
* engineered, modified, repackaged, sold, redistributed or otherwise used in a
|
|
13
|
+
* way not consistent with the End User License Agreement.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
'use strict';
|
|
17
|
+
|
|
18
|
+
const { patchType } = require('../../common');
|
|
19
|
+
const { inspect, isString } = require('@contrast/common');
|
|
20
|
+
|
|
21
|
+
module.exports = function(core) {
|
|
22
|
+
const {
|
|
23
|
+
scopes: { sources, instrumentation },
|
|
24
|
+
patcher,
|
|
25
|
+
depHooks,
|
|
26
|
+
assess: {
|
|
27
|
+
eventFactory: { createPropagationEvent },
|
|
28
|
+
dataflow: { tracker }
|
|
29
|
+
}
|
|
30
|
+
} = core;
|
|
31
|
+
|
|
32
|
+
function getPropagationEvent(params, paramInfo, data) {
|
|
33
|
+
return createPropagationEvent({
|
|
34
|
+
name: 'url.URLSearchParams',
|
|
35
|
+
moduleName: 'url',
|
|
36
|
+
methodName: 'URLSearchParams',
|
|
37
|
+
context: `url.URLSearchParams('${inspect(params)}')`,
|
|
38
|
+
object: {
|
|
39
|
+
value: 'url',
|
|
40
|
+
tracked: false
|
|
41
|
+
},
|
|
42
|
+
result: {
|
|
43
|
+
value: inspect(data.result),
|
|
44
|
+
tracked: true
|
|
45
|
+
},
|
|
46
|
+
args: [{ value: inspect(params), tracked: false }],
|
|
47
|
+
tags: paramInfo.tags,
|
|
48
|
+
history: [paramInfo],
|
|
49
|
+
source: 'P',
|
|
50
|
+
target: 'R',
|
|
51
|
+
stacktraceOpts: {
|
|
52
|
+
constructorOpt: data.hooked,
|
|
53
|
+
prependFrames: [data.orig]
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return core.assess.dataflow.propagation.urlInstrumentation.searchParams = {
|
|
59
|
+
install() {
|
|
60
|
+
depHooks.resolve({ name: 'url' }, (url) => {
|
|
61
|
+
|
|
62
|
+
const name = 'url.URLSearchParams';
|
|
63
|
+
|
|
64
|
+
patcher.patch(url, 'URLSearchParams', {
|
|
65
|
+
name,
|
|
66
|
+
patchType,
|
|
67
|
+
post(data) {
|
|
68
|
+
const { args, obj, result } = data;
|
|
69
|
+
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
|
|
70
|
+
|
|
71
|
+
const [params] = args;
|
|
72
|
+
|
|
73
|
+
if (isString(params)) {
|
|
74
|
+
params.split('&').forEach((query) => {
|
|
75
|
+
const startIdx = query.indexOf('?') + 1;
|
|
76
|
+
const endIdx = query.indexOf('=');
|
|
77
|
+
const key = query.substring(startIdx, endIdx);
|
|
78
|
+
const param = query.substring(endIdx + 1, query.length);
|
|
79
|
+
|
|
80
|
+
const keyInfo = tracker.getData(key);
|
|
81
|
+
const paramInfo = tracker.getData(param);
|
|
82
|
+
|
|
83
|
+
if (keyInfo) {
|
|
84
|
+
const event = getPropagationEvent(params, keyInfo, data);
|
|
85
|
+
if (event) Object.assign(keyInfo, event);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (paramInfo) {
|
|
89
|
+
const event = getPropagationEvent(params, paramInfo, data);
|
|
90
|
+
if (event) Object.assign(paramInfo, event);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const trackedKey = keyInfo?.extern;
|
|
94
|
+
const trackedParam = paramInfo?.extern;
|
|
95
|
+
if (trackedKey) result.delete(key);
|
|
96
|
+
result.set(trackedKey || key, trackedParam || param);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (typeof params === 'object') {
|
|
101
|
+
Object.keys(params).forEach((key) => {
|
|
102
|
+
const paramInfo = tracker.getData(params[key]);
|
|
103
|
+
if (!paramInfo) return;
|
|
104
|
+
|
|
105
|
+
const event = getPropagationEvent(params, paramInfo, data);
|
|
106
|
+
if (!event) return;
|
|
107
|
+
|
|
108
|
+
Object.assign(paramInfo, event);
|
|
109
|
+
const { extern } = paramInfo || tracker.track(params[key], event);
|
|
110
|
+
|
|
111
|
+
if (extern) {
|
|
112
|
+
result.set(key, extern);
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
patcher.patch(obj.prototype, 'toString', {
|
|
118
|
+
name: 'url.URLSearchParams.toString',
|
|
119
|
+
patchType,
|
|
120
|
+
post(data) {
|
|
121
|
+
const { obj: params } = data;
|
|
122
|
+
let i = 0;
|
|
123
|
+
let str = '';
|
|
124
|
+
params.forEach((val, key) => {
|
|
125
|
+
if (i === 0) {
|
|
126
|
+
str = key.concat('=', val);
|
|
127
|
+
} else {
|
|
128
|
+
str = str.concat('&', key, '=', val);
|
|
129
|
+
}
|
|
130
|
+
i++;
|
|
131
|
+
});
|
|
132
|
+
data.result = str;
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
},
|
|
139
|
+
};
|
|
140
|
+
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -24,7 +24,8 @@ module.exports = function(core) {
|
|
|
24
24
|
patcher,
|
|
25
25
|
depHooks,
|
|
26
26
|
assess: {
|
|
27
|
-
|
|
27
|
+
eventFactory: { createPropagationEvent },
|
|
28
|
+
dataflow: { tracker }
|
|
28
29
|
}
|
|
29
30
|
} = core;
|
|
30
31
|
|
|
@@ -42,7 +43,6 @@ module.exports = function(core) {
|
|
|
42
43
|
],
|
|
43
44
|
'pathname',
|
|
44
45
|
'search',
|
|
45
|
-
'searchParams',
|
|
46
46
|
'hash'
|
|
47
47
|
]
|
|
48
48
|
];
|
|
@@ -84,6 +84,7 @@ module.exports = function(core) {
|
|
|
84
84
|
return core.assess.dataflow.propagation.urlInstrumentation.url = {
|
|
85
85
|
install() {
|
|
86
86
|
depHooks.resolve({ name: 'url' }, (url) => {
|
|
87
|
+
const { URLSearchParams } = url;
|
|
87
88
|
const name = 'url.URL';
|
|
88
89
|
patcher.patch(url, 'URL', {
|
|
89
90
|
name,
|
|
@@ -116,33 +117,11 @@ module.exports = function(core) {
|
|
|
116
117
|
const strInfo = tracker.getData(url);
|
|
117
118
|
if (!strInfo) return;
|
|
118
119
|
|
|
119
|
-
const searchParamsProxy = new Proxy(data.result.searchParams, {
|
|
120
|
-
set(obj, prop, value) {
|
|
121
|
-
return Reflect.set(obj, prop, value);
|
|
122
|
-
},
|
|
123
|
-
get(obj, prop, receiver) {
|
|
124
|
-
const val = obj[prop];
|
|
125
|
-
if (val instanceof Function) {
|
|
126
|
-
return function (query) {
|
|
127
|
-
if (typeof query === 'string') {
|
|
128
|
-
const trackedProp = Reflect.get(obj, `_contrast_${query}`);
|
|
129
|
-
if (trackedProp) return trackedProp;
|
|
130
|
-
}
|
|
131
|
-
return val.apply(this === receiver ? obj : this, query);
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
return Reflect.get(obj, prop, receiver);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
|
|
138
120
|
const proxy = new Proxy(data.result, {
|
|
139
121
|
set(obj, prop, value) {
|
|
140
122
|
return Reflect.set(obj, prop, value);
|
|
141
123
|
},
|
|
142
124
|
get(obj, prop) {
|
|
143
|
-
if (prop === 'searchParams') {
|
|
144
|
-
return searchParamsProxy;
|
|
145
|
-
}
|
|
146
125
|
if (prop === 'toString' || prop === 'toJSON') {
|
|
147
126
|
return function() {
|
|
148
127
|
return Reflect.get(obj, '_contrast_href');
|
|
@@ -159,7 +138,7 @@ module.exports = function(core) {
|
|
|
159
138
|
const traverse = function(href, url, keys, idx = 0) {
|
|
160
139
|
let substr = href;
|
|
161
140
|
keys.forEach((key) => {
|
|
162
|
-
if (typeof key === 'string'
|
|
141
|
+
if (typeof key === 'string') {
|
|
163
142
|
const part = url[key];
|
|
164
143
|
if (part !== 'null') {
|
|
165
144
|
|
|
@@ -180,38 +159,13 @@ module.exports = function(core) {
|
|
|
180
159
|
const event = getPropagationEvent(strInfo, partInfo, data);
|
|
181
160
|
if (!event) return;
|
|
182
161
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
const { extern } = partInfo || tracker.track(part, event);
|
|
162
|
+
Object.assign(partInfo, event);
|
|
163
|
+
const { extern } = tracker.track(part, event);
|
|
187
164
|
|
|
188
165
|
if (extern) {
|
|
189
166
|
proxy[`_contrast_${key}`] = extern;
|
|
190
167
|
}
|
|
191
168
|
}
|
|
192
|
-
} else if (key === 'searchParams') {
|
|
193
|
-
const queries = proxy.search.split('&');
|
|
194
|
-
queries.forEach((query) => {
|
|
195
|
-
const startIdx = query.indexOf('?') + 1;
|
|
196
|
-
const endIdx = query.indexOf('=');
|
|
197
|
-
const queryName = query.substring(startIdx, endIdx);
|
|
198
|
-
const queryString = query.substring(endIdx + 1, query.length);
|
|
199
|
-
const queryStringInfo = tracker.getData(queryString);
|
|
200
|
-
if (!queryStringInfo) return;
|
|
201
|
-
|
|
202
|
-
const event = getPropagationEvent(strInfo, queryStringInfo, data);
|
|
203
|
-
|
|
204
|
-
if (!event) return;
|
|
205
|
-
|
|
206
|
-
if (queryStringInfo) {
|
|
207
|
-
Object.assign(queryStringInfo, event);
|
|
208
|
-
}
|
|
209
|
-
const { extern } = queryStringInfo || tracker.track(queryString, event);
|
|
210
|
-
|
|
211
|
-
if (extern) {
|
|
212
|
-
searchParamsProxy[`_contrast_${queryName}`] = extern;
|
|
213
|
-
}
|
|
214
|
-
});
|
|
215
169
|
} else {
|
|
216
170
|
traverse(substr, url, key, 0);
|
|
217
171
|
}
|
|
@@ -219,6 +173,10 @@ module.exports = function(core) {
|
|
|
219
173
|
};
|
|
220
174
|
|
|
221
175
|
traverse(url, result, keys, 0);
|
|
176
|
+
|
|
177
|
+
if (proxy.search) {
|
|
178
|
+
proxy._contrast_searchParams = new URLSearchParams(proxy.search);
|
|
179
|
+
}
|
|
222
180
|
data.result = proxy;
|
|
223
181
|
}
|
|
224
182
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -23,7 +23,8 @@ module.exports = function(core) {
|
|
|
23
23
|
depHooks,
|
|
24
24
|
patcher,
|
|
25
25
|
assess: {
|
|
26
|
-
|
|
26
|
+
eventFactory: { createPropagationEvent },
|
|
27
|
+
dataflow: { tracker }
|
|
27
28
|
}
|
|
28
29
|
} = core;
|
|
29
30
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -30,10 +30,10 @@ module.exports = function(core) {
|
|
|
30
30
|
patcher,
|
|
31
31
|
scopes: { sources },
|
|
32
32
|
assess: {
|
|
33
|
+
eventFactory: { createSinkEvent },
|
|
33
34
|
dataflow: {
|
|
34
35
|
tracker,
|
|
35
36
|
sinks: { isVulnerable, reportFindings },
|
|
36
|
-
eventFactory: { createSinkEvent },
|
|
37
37
|
},
|
|
38
38
|
},
|
|
39
39
|
} = core;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -44,10 +44,10 @@ module.exports = function(core) {
|
|
|
44
44
|
patcher,
|
|
45
45
|
scopes: { sources, instrumentation },
|
|
46
46
|
assess: {
|
|
47
|
+
eventFactory: { createSinkEvent },
|
|
47
48
|
dataflow: {
|
|
48
49
|
tracker,
|
|
49
50
|
sinks: { isVulnerable, reportFindings, reportSafePositive },
|
|
50
|
-
eventFactory: { createSinkEvent },
|
|
51
51
|
},
|
|
52
52
|
},
|
|
53
53
|
} = core;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -39,10 +39,10 @@ module.exports = function(core) {
|
|
|
39
39
|
config,
|
|
40
40
|
scopes: { sources },
|
|
41
41
|
assess: {
|
|
42
|
+
eventFactory: { createSinkEvent },
|
|
42
43
|
dataflow: {
|
|
43
44
|
tracker,
|
|
44
|
-
sinks: { isVulnerable, reportFindings, reportSafePositive }
|
|
45
|
-
eventFactory: { createSinkEvent },
|
|
45
|
+
sinks: { isVulnerable, reportFindings, reportSafePositive }
|
|
46
46
|
},
|
|
47
47
|
},
|
|
48
48
|
} = core;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -58,10 +58,10 @@ module.exports = function(core) {
|
|
|
58
58
|
patcher,
|
|
59
59
|
scopes: { sources },
|
|
60
60
|
assess: {
|
|
61
|
+
eventFactory: { createSinkEvent },
|
|
61
62
|
dataflow: {
|
|
62
63
|
tracker,
|
|
63
64
|
sinks: { isVulnerable, reportFindings, reportSafePositive },
|
|
64
|
-
eventFactory: { createSinkEvent },
|
|
65
65
|
},
|
|
66
66
|
},
|
|
67
67
|
} = core;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -36,10 +36,10 @@ module.exports = function(core) {
|
|
|
36
36
|
patcher,
|
|
37
37
|
scopes: { sources },
|
|
38
38
|
assess: {
|
|
39
|
+
eventFactory: { createSinkEvent },
|
|
39
40
|
dataflow: {
|
|
40
41
|
tracker,
|
|
41
42
|
sinks: { isVulnerable, reportFindings },
|
|
42
|
-
eventFactory: { createSinkEvent },
|
|
43
43
|
},
|
|
44
44
|
},
|
|
45
45
|
} = core;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -46,10 +46,10 @@ module.exports = function(core) {
|
|
|
46
46
|
patcher,
|
|
47
47
|
scopes: { sources, instrumentation },
|
|
48
48
|
assess: {
|
|
49
|
+
eventFactory: { createSinkEvent },
|
|
49
50
|
dataflow: {
|
|
50
51
|
tracker,
|
|
51
52
|
sinks: { isVulnerable, reportFindings, reportSafePositive },
|
|
52
|
-
eventFactory: { createSinkEvent },
|
|
53
53
|
},
|
|
54
54
|
},
|
|
55
55
|
} = core;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright:
|
|
2
|
+
* Copyright: 2023 Contrast Security, Inc
|
|
3
3
|
* Contact: support@contrastsecurity.com
|
|
4
4
|
* License: Commercial
|
|
5
5
|
|
|
@@ -38,13 +38,13 @@ module.exports = function(core) {
|
|
|
38
38
|
patcher,
|
|
39
39
|
scopes: { sources },
|
|
40
40
|
assess: {
|
|
41
|
+
eventFactory: { createSinkEvent },
|
|
41
42
|
dataflow: {
|
|
42
43
|
tracker,
|
|
43
44
|
sinks: {
|
|
44
45
|
isVulnerable,
|
|
45
46
|
reportFindings
|
|
46
47
|
},
|
|
47
|
-
eventFactory: { createSinkEvent },
|
|
48
48
|
},
|
|
49
49
|
},
|
|
50
50
|
} = core;
|