@contrast/assess 1.4.0 → 1.6.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/event-factory.js +41 -83
- package/lib/dataflow/index.js +0 -1
- package/lib/dataflow/propagation/install/array-prototype-join.js +3 -3
- package/lib/dataflow/propagation/install/contrast-methods/add.js +23 -16
- package/lib/dataflow/propagation/install/contrast-methods/tag.js +30 -22
- package/lib/dataflow/propagation/install/decode-uri-component.js +8 -5
- package/lib/dataflow/propagation/install/ejs/escape-xml.js +8 -5
- package/lib/dataflow/propagation/install/encode-uri-component.js +3 -3
- package/lib/dataflow/propagation/install/escape-html.js +10 -7
- package/lib/dataflow/propagation/install/escape.js +8 -5
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +8 -5
- package/lib/dataflow/propagation/install/mysql-connection-escape.js +8 -5
- package/lib/dataflow/propagation/install/pug-runtime-escape.js +3 -3
- package/lib/dataflow/propagation/install/querystring/parse.js +11 -6
- package/lib/dataflow/propagation/install/sql-template-strings.js +3 -3
- package/lib/dataflow/propagation/install/string/concat.js +4 -4
- package/lib/dataflow/propagation/install/string/format-methods.js +2 -2
- package/lib/dataflow/propagation/install/string/html-methods.js +5 -5
- package/lib/dataflow/propagation/install/string/index.js +1 -0
- package/lib/dataflow/propagation/install/string/match.js +3 -3
- package/lib/dataflow/propagation/install/string/replace.js +9 -5
- package/lib/dataflow/propagation/install/string/slice.js +104 -0
- package/lib/dataflow/propagation/install/string/split.js +4 -4
- package/lib/dataflow/propagation/install/string/substring.js +6 -4
- package/lib/dataflow/propagation/install/string/trim.js +2 -2
- package/lib/dataflow/propagation/install/unescape.js +8 -5
- package/lib/dataflow/propagation/install/url/domain-parsers.js +3 -3
- package/lib/dataflow/propagation/install/validator/hooks.js +2 -2
- package/lib/dataflow/propagation/install/validator/methods.js +60 -51
- package/lib/dataflow/sinks/index.js +15 -2
- package/lib/dataflow/sinks/install/child-process.js +224 -0
- package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +47 -23
- package/lib/dataflow/sinks/install/fs.js +136 -0
- package/lib/dataflow/sinks/install/http.js +48 -32
- package/lib/dataflow/sinks/install/koa/index.js +30 -0
- package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +122 -0
- package/lib/dataflow/sinks/install/marsdb.js +135 -0
- package/lib/dataflow/sinks/install/mongodb.js +205 -0
- package/lib/dataflow/sinks/install/mssql.js +19 -13
- package/lib/dataflow/sinks/install/mysql.js +122 -0
- package/lib/dataflow/sinks/install/postgres.js +40 -29
- package/lib/dataflow/sinks/install/sqlite3.js +99 -0
- package/lib/dataflow/sources/handler.js +19 -15
- package/lib/dataflow/sources/index.js +9 -0
- package/lib/dataflow/sources/install/busboy1.js +112 -0
- package/lib/dataflow/sources/install/fastify/fastify.js +23 -29
- package/lib/dataflow/sources/install/fastify/index.js +4 -5
- package/lib/dataflow/sources/install/formidable1.js +91 -0
- package/lib/dataflow/sources/install/http.js +35 -14
- package/lib/dataflow/sources/install/koa/index.js +32 -0
- package/lib/dataflow/sources/install/koa/koa-bodyparsers.js +92 -0
- package/lib/dataflow/sources/install/koa/koa-routers.js +84 -0
- package/lib/dataflow/sources/install/koa/koa2.js +103 -0
- package/lib/dataflow/sources/install/qs6.js +84 -0
- package/lib/dataflow/utils/is-vulnerable.js +1 -1
- package/package.json +2 -2
- package/lib/dataflow/signatures/index.js +0 -2006
- package/lib/dataflow/signatures/mssql.js +0 -49
- package/lib/dataflow/sources/install/fastify/cookie.js +0 -61
|
@@ -14,8 +14,13 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
|
+
|
|
17
18
|
const util = require('util');
|
|
18
19
|
const querystring = require('querystring');
|
|
20
|
+
const {
|
|
21
|
+
DataflowTag: { URL_ENCODED }
|
|
22
|
+
} = require('@contrast/common');
|
|
23
|
+
|
|
19
24
|
const { patchType } = require('../../common');
|
|
20
25
|
const { createSubsetTags, createAppendTags } = require('../../../tag-utils');
|
|
21
26
|
|
|
@@ -46,18 +51,18 @@ module.exports = function(core) {
|
|
|
46
51
|
history: [trackingData],
|
|
47
52
|
object: {
|
|
48
53
|
value: part,
|
|
49
|
-
|
|
54
|
+
tracked: true,
|
|
50
55
|
},
|
|
51
56
|
args: data.origArgs.map((arg) => {
|
|
52
57
|
const argInfo = tracker.getData(arg);
|
|
53
58
|
return {
|
|
54
59
|
value: argInfo ? argInfo.value : util.inspect(arg),
|
|
55
|
-
|
|
60
|
+
tracked: !!argInfo
|
|
56
61
|
};
|
|
57
62
|
}),
|
|
58
63
|
result: {
|
|
59
64
|
value: result,
|
|
60
|
-
|
|
65
|
+
tracked: !!resultInfo
|
|
61
66
|
},
|
|
62
67
|
tags: tagRanges,
|
|
63
68
|
stacktraceOpts: {
|
|
@@ -73,9 +78,9 @@ module.exports = function(core) {
|
|
|
73
78
|
event.tags = createAppendTags(event.tags, resultInfo.tags, 0);
|
|
74
79
|
Object.assign(resultInfo, event);
|
|
75
80
|
}
|
|
76
|
-
if (event.tags[
|
|
77
|
-
delete event.tags[
|
|
78
|
-
event.removedTags = [
|
|
81
|
+
if (event.tags[URL_ENCODED]) {
|
|
82
|
+
delete event.tags[URL_ENCODED];
|
|
83
|
+
event.removedTags = [URL_ENCODED];
|
|
79
84
|
}
|
|
80
85
|
const { extern } = resultInfo || tracker.track(result, event);
|
|
81
86
|
if (extern) {
|
|
@@ -57,13 +57,13 @@ module.exports = function(core) {
|
|
|
57
57
|
name: 'sql-template-strings.SQL',
|
|
58
58
|
object: {
|
|
59
59
|
value: createModuleLabel('sql-template-strings', version),
|
|
60
|
-
|
|
60
|
+
tracked: false
|
|
61
61
|
},
|
|
62
62
|
result: {
|
|
63
63
|
value: resultInfo ? resultInfo.value : resultValue,
|
|
64
|
-
|
|
64
|
+
tracked: true
|
|
65
65
|
},
|
|
66
|
-
args: [{ value: argInfo.value,
|
|
66
|
+
args: [{ value: argInfo.value, tracked: true }],
|
|
67
67
|
tags: newTags,
|
|
68
68
|
addedTags: ['sql-encoded'],
|
|
69
69
|
history,
|
|
@@ -62,10 +62,10 @@ module.exports = function(core) {
|
|
|
62
62
|
|
|
63
63
|
argsData.push({
|
|
64
64
|
value: strInfo?.value ?? str,
|
|
65
|
-
|
|
65
|
+
tracked: !!strInfo
|
|
66
66
|
});
|
|
67
67
|
|
|
68
|
-
globalOffset += str
|
|
68
|
+
globalOffset += `${str}`.length;
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
if (history.size) {
|
|
@@ -73,11 +73,11 @@ module.exports = function(core) {
|
|
|
73
73
|
name: 'String.prototype.concat',
|
|
74
74
|
object: {
|
|
75
75
|
value: objInfo?.value || String(obj),
|
|
76
|
-
|
|
76
|
+
tracked: !!objInfo
|
|
77
77
|
},
|
|
78
78
|
result: {
|
|
79
79
|
value: result,
|
|
80
|
-
|
|
80
|
+
tracked: true
|
|
81
81
|
},
|
|
82
82
|
args: argsData,
|
|
83
83
|
tags: newTags,
|
|
@@ -46,11 +46,11 @@ module.exports = function(core) {
|
|
|
46
46
|
name: `String.prototype.${method}`,
|
|
47
47
|
object: {
|
|
48
48
|
value: objInfo.value,
|
|
49
|
-
|
|
49
|
+
tracked: true
|
|
50
50
|
},
|
|
51
51
|
result: {
|
|
52
52
|
value: result,
|
|
53
|
-
|
|
53
|
+
tracked: true
|
|
54
54
|
},
|
|
55
55
|
args: [],
|
|
56
56
|
tags: objInfo.tags,
|
|
@@ -78,14 +78,14 @@ module.exports = function(core) {
|
|
|
78
78
|
name: 'String.prototype.anchor',
|
|
79
79
|
object: {
|
|
80
80
|
value: objInfo?.value || String(obj),
|
|
81
|
-
|
|
81
|
+
tracked: !!objInfo
|
|
82
82
|
},
|
|
83
83
|
result: {
|
|
84
84
|
value: result,
|
|
85
|
-
|
|
85
|
+
tracked: true
|
|
86
86
|
},
|
|
87
87
|
args: [
|
|
88
|
-
{ value: arg,
|
|
88
|
+
{ value: arg, tracked: !!argInfo }
|
|
89
89
|
],
|
|
90
90
|
tags: adjustTags('anchor', objInfo?.tags, `${arg}`.length, argInfo?.tags),
|
|
91
91
|
history: Array.from(history),
|
|
@@ -126,11 +126,11 @@ module.exports = function(core) {
|
|
|
126
126
|
name: `String.prototype.${method}`,
|
|
127
127
|
object: {
|
|
128
128
|
value: objInfo.value,
|
|
129
|
-
|
|
129
|
+
tracked: true
|
|
130
130
|
},
|
|
131
131
|
result: {
|
|
132
132
|
value: result,
|
|
133
|
-
|
|
133
|
+
tracked: true
|
|
134
134
|
},
|
|
135
135
|
args: [],
|
|
136
136
|
tags: adjustTags(method, objInfo.tags),
|
|
@@ -37,19 +37,19 @@ module.exports = function(core) {
|
|
|
37
37
|
history: [objInfo],
|
|
38
38
|
object: {
|
|
39
39
|
value: objInfo.value,
|
|
40
|
-
|
|
40
|
+
tracked: true,
|
|
41
41
|
},
|
|
42
42
|
args: args.map((arg) => {
|
|
43
43
|
const argInfo = tracker.getData(arg);
|
|
44
44
|
return {
|
|
45
45
|
value: argInfo ? argInfo.value : arg.toString(),
|
|
46
|
-
|
|
46
|
+
tracked: !!argInfo
|
|
47
47
|
};
|
|
48
48
|
}),
|
|
49
49
|
tags,
|
|
50
50
|
result: {
|
|
51
51
|
value: join(result),
|
|
52
|
-
|
|
52
|
+
tracked: false
|
|
53
53
|
},
|
|
54
54
|
stacktraceOpts: {
|
|
55
55
|
constructorOpt: hooked,
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
+
const {
|
|
19
|
+
DataflowTag: { UNTRUSTED }
|
|
20
|
+
} = require('@contrast/common');
|
|
18
21
|
const { patchType } = require('../../common');
|
|
19
22
|
const { createSubsetTags, createAppendTags } = require('../../../tag-utils');
|
|
20
23
|
|
|
@@ -148,7 +151,8 @@ module.exports = function(core) {
|
|
|
148
151
|
!sources.getStore()?.assess ||
|
|
149
152
|
instrumentation.isLocked() ||
|
|
150
153
|
!data.result ||
|
|
151
|
-
|
|
154
|
+
// todo: can we reuse this optimization in other propagators? e.g those performing substring-like operations
|
|
155
|
+
!data._accumTags?.[UNTRUSTED]
|
|
152
156
|
) return;
|
|
153
157
|
|
|
154
158
|
const { _replacementInfo, obj, args, result, hooked, orig } = data;
|
|
@@ -158,19 +162,19 @@ module.exports = function(core) {
|
|
|
158
162
|
history: Array.from(data._history),
|
|
159
163
|
object: {
|
|
160
164
|
value: obj,
|
|
161
|
-
|
|
165
|
+
tracked: !!data._objInfo
|
|
162
166
|
},
|
|
163
167
|
args: [{
|
|
164
168
|
value: args[0].toString(),
|
|
165
|
-
|
|
169
|
+
tracked: !!tracker.getData(args[0])
|
|
166
170
|
},
|
|
167
171
|
{
|
|
168
172
|
value: data._replacement,
|
|
169
|
-
|
|
173
|
+
tracked: !!_replacementInfo
|
|
170
174
|
}],
|
|
171
175
|
result: {
|
|
172
176
|
value: result,
|
|
173
|
-
|
|
177
|
+
tracked: true
|
|
174
178
|
},
|
|
175
179
|
tags: data._accumTags,
|
|
176
180
|
stacktraceOpts: {
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright: 2022 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
|
+
'use strict';
|
|
16
|
+
const { patchType } = require('../../common');
|
|
17
|
+
const { createSubsetTags } = require('../../../tag-utils');
|
|
18
|
+
|
|
19
|
+
module.exports = function(core) {
|
|
20
|
+
const {
|
|
21
|
+
scopes: { sources, instrumentation },
|
|
22
|
+
patcher,
|
|
23
|
+
assess: {
|
|
24
|
+
dataflow: { tracker, eventFactory: { createPropagationEvent } }
|
|
25
|
+
}
|
|
26
|
+
} = core;
|
|
27
|
+
|
|
28
|
+
function calculateSubsetRangeForSlice({ obj, args }) {
|
|
29
|
+
let [start, end] = args;
|
|
30
|
+
const hasSingleArg = end === undefined;
|
|
31
|
+
|
|
32
|
+
if (start < 0 && hasSingleArg || start < 0 && end < 0) {
|
|
33
|
+
start = obj.length - Math.abs(start);
|
|
34
|
+
end = obj.length - (Math.abs(end) || 0);
|
|
35
|
+
} else if (start > 0 && end < 0) {
|
|
36
|
+
end = obj.length - (Math.abs(end) || 0);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const subsetLen = (hasSingleArg ? obj.length - start : Math.abs(end - start)) - 1;
|
|
40
|
+
|
|
41
|
+
return {
|
|
42
|
+
startIdx: start,
|
|
43
|
+
subsetLen
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return core.assess.dataflow.propagation.stringInstrumentation.slice = {
|
|
48
|
+
install() {
|
|
49
|
+
const name = 'String.prototype.slice';
|
|
50
|
+
|
|
51
|
+
patcher.patch(String.prototype, 'slice', {
|
|
52
|
+
name,
|
|
53
|
+
patchType,
|
|
54
|
+
post(data) {
|
|
55
|
+
const { name, args, obj, result, hooked, orig } = data;
|
|
56
|
+
if (!result || !sources.getStore() || instrumentation.isLocked()) return;
|
|
57
|
+
|
|
58
|
+
const objInfo = tracker.getData(obj);
|
|
59
|
+
if (!objInfo) return;
|
|
60
|
+
|
|
61
|
+
const rInfo = tracker.getData(result);
|
|
62
|
+
if (rInfo) {
|
|
63
|
+
// this may happen w/ trackedStr.slice(0) => trackedStr
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const { startIdx, subsetLen } = calculateSubsetRangeForSlice(data);
|
|
68
|
+
const tags = createSubsetTags(objInfo.tags, startIdx, subsetLen);
|
|
69
|
+
if (!tags) return;
|
|
70
|
+
|
|
71
|
+
const event = createPropagationEvent({
|
|
72
|
+
name,
|
|
73
|
+
history: [objInfo],
|
|
74
|
+
object: {
|
|
75
|
+
value: obj,
|
|
76
|
+
tracked: true,
|
|
77
|
+
},
|
|
78
|
+
args: args.map((arg) => ({
|
|
79
|
+
value: arg.toString(),
|
|
80
|
+
tracked: false
|
|
81
|
+
})),
|
|
82
|
+
result: {
|
|
83
|
+
value: result,
|
|
84
|
+
tracked: true
|
|
85
|
+
},
|
|
86
|
+
tags,
|
|
87
|
+
stacktraceOpts: {
|
|
88
|
+
constructorOpt: hooked,
|
|
89
|
+
prependFrames: [orig]
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
const { extern } = tracker.track(result, event);
|
|
93
|
+
|
|
94
|
+
if (extern) {
|
|
95
|
+
data.result = extern;
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
});
|
|
99
|
+
},
|
|
100
|
+
uninstall() {
|
|
101
|
+
String.prototype.slice = patcher.unwrap(String.prototype.slice);
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
};
|
|
@@ -50,7 +50,7 @@ module.exports = function(core) {
|
|
|
50
50
|
) return;
|
|
51
51
|
|
|
52
52
|
const objInfo = tracker.getData(obj);
|
|
53
|
-
if (!objInfo) return;
|
|
53
|
+
if (!objInfo || obj === result[0]) return;
|
|
54
54
|
|
|
55
55
|
let idx = 0;
|
|
56
56
|
for (let i = 0; i < result.length; i++) {
|
|
@@ -68,19 +68,19 @@ module.exports = function(core) {
|
|
|
68
68
|
history: [objInfo],
|
|
69
69
|
object: {
|
|
70
70
|
value: obj,
|
|
71
|
-
|
|
71
|
+
tracked: true,
|
|
72
72
|
},
|
|
73
73
|
args: args.map((arg) => {
|
|
74
74
|
const argInfo = tracker.getData(arg);
|
|
75
75
|
return {
|
|
76
76
|
value: argInfo ? argInfo.value : arg.toString(),
|
|
77
|
-
|
|
77
|
+
tracked: !!argInfo
|
|
78
78
|
};
|
|
79
79
|
}),
|
|
80
80
|
tags,
|
|
81
81
|
result: {
|
|
82
82
|
value: join(result),
|
|
83
|
-
|
|
83
|
+
tracked: false
|
|
84
84
|
},
|
|
85
85
|
stacktraceOpts: {
|
|
86
86
|
constructorOpt: hooked,
|
|
@@ -83,21 +83,23 @@ module.exports = function(core) {
|
|
|
83
83
|
history: [objInfo],
|
|
84
84
|
object: {
|
|
85
85
|
value: obj,
|
|
86
|
-
|
|
86
|
+
tracked: true,
|
|
87
87
|
},
|
|
88
88
|
args: args.map((arg) => ({
|
|
89
89
|
value: arg.toString(),
|
|
90
|
-
|
|
90
|
+
tracked: false
|
|
91
91
|
})),
|
|
92
92
|
result: {
|
|
93
93
|
value: result,
|
|
94
|
-
|
|
94
|
+
tracked: true
|
|
95
95
|
},
|
|
96
96
|
tags,
|
|
97
|
+
source: 'O',
|
|
97
98
|
stacktraceOpts: {
|
|
98
99
|
constructorOpt: hooked,
|
|
99
100
|
prependFrames: [orig]
|
|
100
|
-
}
|
|
101
|
+
},
|
|
102
|
+
target: 'R',
|
|
101
103
|
});
|
|
102
104
|
const { extern } = tracker.track(result, event);
|
|
103
105
|
|
|
@@ -15,6 +15,9 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
+
const {
|
|
19
|
+
DataflowTag: { WEAK_URL_ENCODED }
|
|
20
|
+
} = require('@contrast/common');
|
|
18
21
|
const {
|
|
19
22
|
createFullLengthCopyTags
|
|
20
23
|
} = require('../../tag-utils');
|
|
@@ -45,7 +48,7 @@ module.exports = function(core) {
|
|
|
45
48
|
const resultInfo = tracker.getData(result);
|
|
46
49
|
const history = [argInfo];
|
|
47
50
|
const newTags = createFullLengthCopyTags(argInfo.tags, result.length);
|
|
48
|
-
delete newTags[
|
|
51
|
+
delete newTags[WEAK_URL_ENCODED];
|
|
49
52
|
|
|
50
53
|
if (!Object.keys(newTags).length) return;
|
|
51
54
|
|
|
@@ -53,16 +56,16 @@ module.exports = function(core) {
|
|
|
53
56
|
name: 'global.unescape',
|
|
54
57
|
object: {
|
|
55
58
|
value: createObjectLabel('global'),
|
|
56
|
-
|
|
59
|
+
tracked: false
|
|
57
60
|
},
|
|
58
61
|
result: {
|
|
59
62
|
value: resultInfo ? resultInfo.value : result,
|
|
60
|
-
|
|
63
|
+
tracked: true
|
|
61
64
|
},
|
|
62
|
-
args: [{ value: argInfo.value,
|
|
65
|
+
args: [{ value: argInfo.value, tracked: true }],
|
|
63
66
|
tags: newTags,
|
|
64
67
|
history,
|
|
65
|
-
removedTags: [
|
|
68
|
+
removedTags: [WEAK_URL_ENCODED],
|
|
66
69
|
stacktraceOpts: {
|
|
67
70
|
constructorOpt: hooked,
|
|
68
71
|
prependFrames: [orig]
|
|
@@ -52,13 +52,13 @@ module.exports = function(core) {
|
|
|
52
52
|
name: `url.${method}`,
|
|
53
53
|
object: {
|
|
54
54
|
value: createModuleLabel('url', version),
|
|
55
|
-
|
|
55
|
+
tracked: false
|
|
56
56
|
},
|
|
57
57
|
result: {
|
|
58
58
|
value: resultInfo ? resultInfo.value : result,
|
|
59
|
-
|
|
59
|
+
tracked: true
|
|
60
60
|
},
|
|
61
|
-
args: [{ value: argInfo.value,
|
|
61
|
+
args: [{ value: argInfo.value, tracked: true }],
|
|
62
62
|
tags: createFullLengthCopyTags(argInfo.tags, result.length) || [],
|
|
63
63
|
history,
|
|
64
64
|
source: 'P',
|
|
@@ -33,11 +33,11 @@ module.exports = function(core) {
|
|
|
33
33
|
history: [{ ...trackingData }],
|
|
34
34
|
args: [{
|
|
35
35
|
value: data.args[0],
|
|
36
|
-
|
|
36
|
+
tracked: true
|
|
37
37
|
}],
|
|
38
38
|
result: {
|
|
39
39
|
value: data.result,
|
|
40
|
-
|
|
40
|
+
tracked: !!tracker.getData(data.result)
|
|
41
41
|
},
|
|
42
42
|
tags: {
|
|
43
43
|
...trackingData.tags,
|
|
@@ -15,57 +15,66 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
+
const {
|
|
19
|
+
DataflowTag: {
|
|
20
|
+
ALPHANUM_SPACE_HYPHEN,
|
|
21
|
+
CUSTOM_VALIDATED,
|
|
22
|
+
HTML_ENCODED,
|
|
23
|
+
LIMITED_CHARS,
|
|
24
|
+
}
|
|
25
|
+
} = require('@contrast/common');
|
|
26
|
+
|
|
18
27
|
module.exports = {
|
|
19
28
|
validators: {
|
|
20
|
-
isAfter:
|
|
21
|
-
isAlpha:
|
|
22
|
-
isAlphanumeric:
|
|
23
|
-
isBase32:
|
|
24
|
-
isBase58:
|
|
25
|
-
isBase64:
|
|
26
|
-
isBefore:
|
|
27
|
-
isBIC:
|
|
28
|
-
isBoolean:
|
|
29
|
-
isBtcAddress:
|
|
30
|
-
isCreditCard:
|
|
31
|
-
isDate:
|
|
32
|
-
isDecimal:
|
|
33
|
-
isEAN:
|
|
34
|
-
isEthereumAddress:
|
|
35
|
-
isFloat:
|
|
36
|
-
isHash:
|
|
37
|
-
isHexadecimal:
|
|
38
|
-
isHexColor:
|
|
39
|
-
isHSL:
|
|
40
|
-
isIBAN:
|
|
41
|
-
isIdentityCard:
|
|
42
|
-
isIMEI:
|
|
43
|
-
isInt:
|
|
44
|
-
isIP:
|
|
45
|
-
isIPRange:
|
|
46
|
-
isISBN:
|
|
47
|
-
isISIN:
|
|
48
|
-
isISO8601:
|
|
49
|
-
isISO31661Alpha2:
|
|
50
|
-
isISO31661Alpha3:
|
|
51
|
-
isISRC:
|
|
52
|
-
isISSN:
|
|
53
|
-
isJWT:
|
|
54
|
-
isLatLong:
|
|
55
|
-
isLicensePlate:
|
|
56
|
-
isMACAddress:
|
|
57
|
-
isMagnetURI:
|
|
58
|
-
isMD5:
|
|
59
|
-
isMobilePhone:
|
|
60
|
-
isNumeric:
|
|
61
|
-
isOctal:
|
|
62
|
-
isPassportNumber:
|
|
63
|
-
isPostalCode:
|
|
64
|
-
isSemVer:
|
|
65
|
-
isTaxID:
|
|
66
|
-
isUUID:
|
|
67
|
-
isVAT:
|
|
68
|
-
matches:
|
|
29
|
+
isAfter: ALPHANUM_SPACE_HYPHEN,
|
|
30
|
+
isAlpha: ALPHANUM_SPACE_HYPHEN,
|
|
31
|
+
isAlphanumeric: ALPHANUM_SPACE_HYPHEN,
|
|
32
|
+
isBase32: ALPHANUM_SPACE_HYPHEN,
|
|
33
|
+
isBase58: ALPHANUM_SPACE_HYPHEN,
|
|
34
|
+
isBase64: ALPHANUM_SPACE_HYPHEN,
|
|
35
|
+
isBefore: ALPHANUM_SPACE_HYPHEN,
|
|
36
|
+
isBIC: ALPHANUM_SPACE_HYPHEN,
|
|
37
|
+
isBoolean: LIMITED_CHARS,
|
|
38
|
+
isBtcAddress: ALPHANUM_SPACE_HYPHEN,
|
|
39
|
+
isCreditCard: LIMITED_CHARS,
|
|
40
|
+
isDate: LIMITED_CHARS,
|
|
41
|
+
isDecimal: LIMITED_CHARS,
|
|
42
|
+
isEAN: LIMITED_CHARS,
|
|
43
|
+
isEthereumAddress: ALPHANUM_SPACE_HYPHEN,
|
|
44
|
+
isFloat: LIMITED_CHARS,
|
|
45
|
+
isHash: ALPHANUM_SPACE_HYPHEN,
|
|
46
|
+
isHexadecimal: ALPHANUM_SPACE_HYPHEN,
|
|
47
|
+
isHexColor: ALPHANUM_SPACE_HYPHEN,
|
|
48
|
+
isHSL: ALPHANUM_SPACE_HYPHEN,
|
|
49
|
+
isIBAN: LIMITED_CHARS,
|
|
50
|
+
isIdentityCard: ALPHANUM_SPACE_HYPHEN,
|
|
51
|
+
isIMEI: LIMITED_CHARS,
|
|
52
|
+
isInt: LIMITED_CHARS,
|
|
53
|
+
isIP: LIMITED_CHARS,
|
|
54
|
+
isIPRange: LIMITED_CHARS,
|
|
55
|
+
isISBN: LIMITED_CHARS,
|
|
56
|
+
isISIN: LIMITED_CHARS,
|
|
57
|
+
isISO8601: ALPHANUM_SPACE_HYPHEN,
|
|
58
|
+
isISO31661Alpha2: ALPHANUM_SPACE_HYPHEN,
|
|
59
|
+
isISO31661Alpha3: ALPHANUM_SPACE_HYPHEN,
|
|
60
|
+
isISRC: ALPHANUM_SPACE_HYPHEN,
|
|
61
|
+
isISSN: LIMITED_CHARS,
|
|
62
|
+
isJWT: ALPHANUM_SPACE_HYPHEN,
|
|
63
|
+
isLatLong: LIMITED_CHARS,
|
|
64
|
+
isLicensePlate: ALPHANUM_SPACE_HYPHEN,
|
|
65
|
+
isMACAddress: ALPHANUM_SPACE_HYPHEN,
|
|
66
|
+
isMagnetURI: ALPHANUM_SPACE_HYPHEN,
|
|
67
|
+
isMD5: ALPHANUM_SPACE_HYPHEN,
|
|
68
|
+
isMobilePhone: LIMITED_CHARS,
|
|
69
|
+
isNumeric: LIMITED_CHARS,
|
|
70
|
+
isOctal: ALPHANUM_SPACE_HYPHEN,
|
|
71
|
+
isPassportNumber: LIMITED_CHARS,
|
|
72
|
+
isPostalCode: LIMITED_CHARS,
|
|
73
|
+
isSemVer: LIMITED_CHARS,
|
|
74
|
+
isTaxID: LIMITED_CHARS,
|
|
75
|
+
isUUID: ALPHANUM_SPACE_HYPHEN,
|
|
76
|
+
isVAT: ALPHANUM_SPACE_HYPHEN,
|
|
77
|
+
matches: CUSTOM_VALIDATED,
|
|
69
78
|
},
|
|
70
79
|
untrackers: [
|
|
71
80
|
'equals',
|
|
@@ -74,9 +83,9 @@ module.exports = {
|
|
|
74
83
|
'isRFC3339'
|
|
75
84
|
],
|
|
76
85
|
sanitizers: {
|
|
77
|
-
escape:
|
|
86
|
+
escape: HTML_ENCODED
|
|
78
87
|
},
|
|
79
88
|
custom: {
|
|
80
|
-
isEmail:
|
|
89
|
+
isEmail: LIMITED_CHARS
|
|
81
90
|
}
|
|
82
91
|
};
|
|
@@ -21,21 +21,34 @@ const { isSafeContentType } = require('../utils/is-safe-content-type');
|
|
|
21
21
|
|
|
22
22
|
module.exports = function (core) {
|
|
23
23
|
const {
|
|
24
|
-
messages
|
|
24
|
+
messages,
|
|
25
|
+
scopes: { sources }
|
|
25
26
|
} = core;
|
|
26
27
|
|
|
27
28
|
const sinks = core.assess.dataflow.sinks = {
|
|
28
29
|
isVulnerable,
|
|
29
30
|
isSafeContentType,
|
|
30
31
|
reportFindings(data) {
|
|
31
|
-
|
|
32
|
+
const store = sources.getStore();
|
|
33
|
+
// these events need source correlation
|
|
34
|
+
messages.emit(Event.ASSESS_DATAFLOW_FINDING, {
|
|
35
|
+
sourceInfo: store?.sourceInfo,
|
|
36
|
+
...data
|
|
37
|
+
});
|
|
32
38
|
},
|
|
33
39
|
};
|
|
34
40
|
|
|
35
41
|
require('./install/fastify')(core);
|
|
42
|
+
require('./install/koa')(core);
|
|
43
|
+
require('./install/child-process')(core);
|
|
44
|
+
require('./install/fs')(core);
|
|
36
45
|
require('./install/http')(core);
|
|
46
|
+
require('./install/mongodb')(core);
|
|
37
47
|
require('./install/mssql')(core);
|
|
48
|
+
require('./install/mysql')(core);
|
|
38
49
|
require('./install/postgres')(core);
|
|
50
|
+
require('./install/sqlite3')(core);
|
|
51
|
+
require('./install/marsdb')(core);
|
|
39
52
|
|
|
40
53
|
sinks.install = function() {
|
|
41
54
|
callChildComponentMethodsSync(core.assess.dataflow.sinks, 'install');
|