@contrast/assess 1.53.0 → 1.54.1
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/math.js +0 -1
- package/lib/dataflow/propagation/common.js +6 -6
- package/lib/dataflow/propagation/install/JSON/parse.js +7 -3
- package/lib/dataflow/propagation/install/JSON/stringify.js +7 -6
- package/lib/dataflow/propagation/install/array-prototype-join.js +5 -8
- package/lib/dataflow/propagation/install/buffer.js +4 -4
- package/lib/dataflow/propagation/install/contrast-methods/add.js +42 -38
- package/lib/dataflow/propagation/install/contrast-methods/string.js +4 -2
- package/lib/dataflow/propagation/install/contrast-methods/tag.js +3 -1
- package/lib/dataflow/propagation/install/decode-uri-component.js +5 -7
- package/lib/dataflow/propagation/install/ejs/escape-xml.js +4 -3
- package/lib/dataflow/propagation/install/ejs/template.js +1 -1
- package/lib/dataflow/propagation/install/encode-uri.js +5 -7
- package/lib/dataflow/propagation/install/escape-html.js +4 -3
- package/lib/dataflow/propagation/install/escape.js +5 -7
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +4 -3
- package/lib/dataflow/propagation/install/joi/boolean.js +1 -3
- package/lib/dataflow/propagation/install/joi/expression.js +1 -3
- package/lib/dataflow/propagation/install/joi/number.js +1 -3
- package/lib/dataflow/propagation/install/joi/string-schema.js +2 -6
- package/lib/dataflow/propagation/install/joi/utils.js +2 -4
- package/lib/dataflow/propagation/install/joi/values.js +1 -3
- package/lib/dataflow/propagation/install/mongoose/schema-map.js +1 -3
- package/lib/dataflow/propagation/install/mongoose/schema-mixed.js +1 -3
- package/lib/dataflow/propagation/install/mongoose/schema-string.js +4 -5
- package/lib/dataflow/propagation/install/mustache-escape.js +4 -3
- package/lib/dataflow/propagation/install/mysql-connection-escape.js +9 -8
- package/lib/dataflow/propagation/install/path/basename.js +6 -7
- package/lib/dataflow/propagation/install/path/common.js +1 -0
- package/lib/dataflow/propagation/install/path/dirname.js +6 -8
- package/lib/dataflow/propagation/install/path/extname.js +8 -22
- package/lib/dataflow/propagation/install/path/format.js +6 -10
- package/lib/dataflow/propagation/install/path/join-and-resolve.js +7 -13
- package/lib/dataflow/propagation/install/path/normalize.js +8 -18
- package/lib/dataflow/propagation/install/path/parse.js +8 -18
- package/lib/dataflow/propagation/install/path/relative.js +8 -15
- package/lib/dataflow/propagation/install/path/toNamespacedPath.js +7 -18
- package/lib/dataflow/propagation/install/pug/index.js +1 -1
- package/lib/dataflow/propagation/install/pug-runtime-escape.js +6 -5
- package/lib/dataflow/propagation/install/querystring/escape.js +3 -1
- package/lib/dataflow/propagation/install/querystring/parse.js +3 -2
- package/lib/dataflow/propagation/install/querystring/stringify.js +4 -4
- package/lib/dataflow/propagation/install/reg-exp-prototype-exec.js +4 -3
- package/lib/dataflow/propagation/install/sequelize/query-generator.js +0 -1
- package/lib/dataflow/propagation/install/sequelize/sql-string.js +16 -17
- package/lib/dataflow/propagation/install/sql-template-strings.js +6 -10
- package/lib/dataflow/propagation/install/string/concat.js +4 -4
- package/lib/dataflow/propagation/install/string/format-methods.js +4 -4
- package/lib/dataflow/propagation/install/string/html-methods.js +5 -6
- package/lib/dataflow/propagation/install/string/index.js +4 -3
- package/lib/dataflow/propagation/install/string/match-all.js +7 -6
- package/lib/dataflow/propagation/install/string/match.js +10 -9
- package/lib/dataflow/propagation/install/string/replace.js +173 -158
- package/lib/dataflow/propagation/install/string/slice.js +4 -3
- package/lib/dataflow/propagation/install/string/split.js +11 -11
- package/lib/dataflow/propagation/install/string/substring.js +4 -3
- package/lib/dataflow/propagation/install/string/trim.js +4 -3
- package/lib/dataflow/propagation/install/unescape.js +6 -14
- package/lib/dataflow/propagation/install/url/domain-parsers.js +6 -5
- package/lib/dataflow/propagation/install/url/parse.js +17 -17
- package/lib/dataflow/propagation/install/url/searchParams.js +36 -25
- package/lib/dataflow/propagation/install/url/url.js +3 -2
- package/lib/dataflow/propagation/install/util-format.js +4 -3
- package/lib/dataflow/propagation/install/validator/hooks.js +0 -1
- package/lib/dataflow/sinks/install/eval.js +3 -1
- package/lib/dataflow/sinks/install/function.js +3 -4
- package/lib/dataflow/sinks/install/marsdb.js +3 -1
- package/lib/dataflow/sinks/install/mongodb.js +3 -1
- package/lib/dataflow/sinks/install/mssql.js +4 -3
- package/lib/dataflow/sinks/install/mysql.js +3 -1
- package/lib/dataflow/sinks/install/restify.js +3 -1
- package/lib/dataflow/sinks/install/sqlite3.js +4 -2
- package/lib/dataflow/sinks/install/vm.js +6 -4
- package/lib/dataflow/sources/handler.js +2 -3
- package/lib/dataflow/sources/install/fastify/fastify.js +4 -4
- package/lib/dataflow/tag-utils.js +15 -1
- package/lib/dataflow/tracker.js +0 -5
- package/lib/event-factory.js +1 -1
- package/lib/session-configuration/install/express-session.js +0 -1
- package/lib/session-configuration/install/fastify-cookie.js +0 -3
- package/lib/session-configuration/install/hapi.js +0 -1
- package/lib/session-configuration/install/koa.js +0 -3
- package/package.json +10 -10
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
18
|
const { createFullLengthCopyTags } = require('../../../tag-utils');
|
|
19
|
-
const { patchType
|
|
19
|
+
const { patchType } = require('../../common');
|
|
20
20
|
|
|
21
21
|
module.exports = function(core) {
|
|
22
22
|
const {
|
|
@@ -40,7 +40,7 @@ module.exports = function(core) {
|
|
|
40
40
|
patchType,
|
|
41
41
|
usePerf: 'sync',
|
|
42
42
|
post(data) {
|
|
43
|
-
const { args, result, hooked
|
|
43
|
+
const { args, result, hooked } = data;
|
|
44
44
|
if (!result || !args[0] || !getPropagatorContext()) return;
|
|
45
45
|
|
|
46
46
|
const argInfo = tracker.getData(args[0]);
|
|
@@ -54,9 +54,11 @@ module.exports = function(core) {
|
|
|
54
54
|
name,
|
|
55
55
|
moduleName: 'url',
|
|
56
56
|
methodName: method,
|
|
57
|
-
context
|
|
57
|
+
get context() {
|
|
58
|
+
return `url.${method}('${argInfo.value}')`;
|
|
59
|
+
},
|
|
58
60
|
object: {
|
|
59
|
-
value:
|
|
61
|
+
value: 'url',
|
|
60
62
|
tracked: false
|
|
61
63
|
},
|
|
62
64
|
result: {
|
|
@@ -70,7 +72,6 @@ module.exports = function(core) {
|
|
|
70
72
|
target: 'R',
|
|
71
73
|
stacktraceOpts: {
|
|
72
74
|
constructorOpt: hooked,
|
|
73
|
-
prependFrames: [orig]
|
|
74
75
|
},
|
|
75
76
|
});
|
|
76
77
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
18
|
const { patchType } = require('../../common');
|
|
19
|
+
const { createSubsetTags } = require('../../../tag-utils');
|
|
19
20
|
|
|
20
21
|
module.exports = function(core) {
|
|
21
22
|
const {
|
|
@@ -51,12 +52,14 @@ module.exports = function(core) {
|
|
|
51
52
|
]
|
|
52
53
|
];
|
|
53
54
|
|
|
54
|
-
function getPropagationEvent(argInfo,
|
|
55
|
+
function getPropagationEvent(argInfo, { value, tags }, { name, result, hooked, orig }, parseQueryString = false) {
|
|
55
56
|
return createPropagationEvent({
|
|
56
57
|
name,
|
|
57
58
|
moduleName: 'url',
|
|
58
59
|
methodName: 'parse',
|
|
59
|
-
context
|
|
60
|
+
get context() {
|
|
61
|
+
return `url.parse('${argInfo.value += parseQueryString ? "', true" : ''})`;
|
|
62
|
+
},
|
|
60
63
|
object: {
|
|
61
64
|
value: 'url',
|
|
62
65
|
tracked: false
|
|
@@ -65,14 +68,13 @@ module.exports = function(core) {
|
|
|
65
68
|
value: inspect(result),
|
|
66
69
|
tracked: true
|
|
67
70
|
},
|
|
68
|
-
args: [{ value
|
|
69
|
-
tags
|
|
70
|
-
history: [{ ...
|
|
71
|
+
args: [{ value, tracked: true }],
|
|
72
|
+
tags,
|
|
73
|
+
history: [{ ...argInfo }],
|
|
71
74
|
source: 'P',
|
|
72
75
|
target: 'R',
|
|
73
76
|
stacktraceOpts: {
|
|
74
77
|
constructorOpt: hooked,
|
|
75
|
-
prependFrames: [orig]
|
|
76
78
|
},
|
|
77
79
|
});
|
|
78
80
|
}
|
|
@@ -80,7 +82,6 @@ module.exports = function(core) {
|
|
|
80
82
|
return core.assess.dataflow.propagation.urlInstrumentation.parse = {
|
|
81
83
|
install() {
|
|
82
84
|
depHooks.resolve({ name: 'url', version: '*' }, (url) => {
|
|
83
|
-
|
|
84
85
|
const name = 'url.parse';
|
|
85
86
|
|
|
86
87
|
patcher.patch(url, 'parse', {
|
|
@@ -98,7 +99,7 @@ module.exports = function(core) {
|
|
|
98
99
|
|
|
99
100
|
const metadata = { name, result, hooked, orig };
|
|
100
101
|
const traverse = function(href, url, keys, idx = 0) {
|
|
101
|
-
|
|
102
|
+
const substr = href;
|
|
102
103
|
keys.forEach((key) => {
|
|
103
104
|
if (typeof key === 'string') {
|
|
104
105
|
const part = result[key];
|
|
@@ -117,20 +118,19 @@ module.exports = function(core) {
|
|
|
117
118
|
});
|
|
118
119
|
return;
|
|
119
120
|
} else {
|
|
120
|
-
const index = href.indexOf(part, idx - 1);
|
|
121
|
-
|
|
121
|
+
const index = url.href.indexOf(part, idx - 1);
|
|
122
|
+
const substrTags = createSubsetTags(argInfo.tags, index, part.length);
|
|
123
|
+
if (!substrTags) return;
|
|
122
124
|
idx += part.length;
|
|
123
|
-
}
|
|
124
125
|
|
|
125
|
-
|
|
126
|
-
if (!partInfo) return;
|
|
126
|
+
const event = getPropagationEvent(argInfo, { value: part, tags: substrTags }, metadata);
|
|
127
127
|
|
|
128
|
-
|
|
128
|
+
if (!event) return;
|
|
129
129
|
|
|
130
|
-
|
|
130
|
+
const { extern } = tracker.track(part, event);
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
|
|
132
|
+
if (extern) result[key] = extern;
|
|
133
|
+
}
|
|
134
134
|
}
|
|
135
135
|
} else {
|
|
136
136
|
traverse(substr, url, key, 0);
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
-
const { isString, primordials: { StringPrototypeConcat, StringPrototypeReplaceAll } } = require('@contrast/common');
|
|
19
|
-
const { createAppendTags } = require('../../../tag-utils');
|
|
18
|
+
const { isString, primordials: { StringPrototypeConcat, StringPrototypeReplaceAll, StringPrototypeSplit, StringPrototypeSubstring } } = require('@contrast/common');
|
|
19
|
+
const { createAppendTags, createSubsetTags } = require('../../../tag-utils');
|
|
20
20
|
const { patchType } = require('../../common');
|
|
21
21
|
|
|
22
22
|
module.exports = function(core) {
|
|
@@ -31,12 +31,14 @@ module.exports = function(core) {
|
|
|
31
31
|
}
|
|
32
32
|
} = core;
|
|
33
33
|
|
|
34
|
-
function getPropagationEvent(params,
|
|
34
|
+
function getPropagationEvent(params, tags, data, history) {
|
|
35
35
|
return createPropagationEvent({
|
|
36
36
|
name: 'url.URLSearchParams',
|
|
37
37
|
moduleName: 'url',
|
|
38
38
|
methodName: 'URLSearchParams',
|
|
39
|
-
context
|
|
39
|
+
get context() {
|
|
40
|
+
return `url.URLSearchParams('${inspect(params)}')`;
|
|
41
|
+
},
|
|
40
42
|
object: {
|
|
41
43
|
value: 'url',
|
|
42
44
|
tracked: false
|
|
@@ -46,13 +48,12 @@ module.exports = function(core) {
|
|
|
46
48
|
tracked: true
|
|
47
49
|
},
|
|
48
50
|
args: [{ value: inspect(params), tracked: false }],
|
|
49
|
-
tags
|
|
50
|
-
history
|
|
51
|
+
tags,
|
|
52
|
+
history,
|
|
51
53
|
source: 'P',
|
|
52
54
|
target: 'R',
|
|
53
55
|
stacktraceOpts: {
|
|
54
56
|
constructorOpt: data.hooked,
|
|
55
|
-
prependFrames: [data.orig]
|
|
56
57
|
},
|
|
57
58
|
});
|
|
58
59
|
}
|
|
@@ -73,28 +74,39 @@ module.exports = function(core) {
|
|
|
73
74
|
const [params] = args;
|
|
74
75
|
|
|
75
76
|
if (isString(params)) {
|
|
76
|
-
|
|
77
|
+
const paramsInfo = tracker.getData(params);
|
|
78
|
+
if (!paramsInfo) return;
|
|
79
|
+
let idx = 0;
|
|
80
|
+
StringPrototypeSplit.call(params, '&').forEach((query) => {
|
|
77
81
|
const endIdx = query.indexOf('=');
|
|
78
82
|
// we don't want to create a propagation event by splitting off
|
|
79
83
|
// the '?'. so if there start at index 1 else 0.
|
|
80
|
-
const
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
const keyIdx = query[0] === '?' ? 1 : 0;
|
|
85
|
+
const key = StringPrototypeSubstring.call(query, keyIdx, endIdx);
|
|
86
|
+
const param = StringPrototypeSubstring.call(query, endIdx + 1, query.length);
|
|
87
|
+
|
|
88
|
+
idx += params.indexOf(query, idx);
|
|
89
|
+
const keyTags = createSubsetTags(paramsInfo.tags, idx + keyIdx, key.length);
|
|
90
|
+
const paramTags = createSubsetTags(paramsInfo.tags, key.length + idx + keyIdx + 1, param.length);
|
|
91
|
+
|
|
92
|
+
if (keyTags) {
|
|
93
|
+
const event = getPropagationEvent(params, keyTags, data, [paramsInfo]);
|
|
94
|
+
if (event) {
|
|
95
|
+
const { extern } = tracker.track(key, event);
|
|
96
|
+
if (extern) {
|
|
97
|
+
result.delete(key);
|
|
98
|
+
result.set(extern, param);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
89
101
|
}
|
|
90
102
|
|
|
91
|
-
if (
|
|
92
|
-
const event = getPropagationEvent(params,
|
|
93
|
-
if (event)
|
|
103
|
+
if (paramTags) {
|
|
104
|
+
const event = getPropagationEvent(params, paramTags, data, [paramsInfo]);
|
|
105
|
+
if (event) {
|
|
106
|
+
const { extern } = tracker.track(param, event);
|
|
107
|
+
if (extern) result.set(key, extern);
|
|
108
|
+
}
|
|
94
109
|
}
|
|
95
|
-
|
|
96
|
-
if (keyInfo) result.delete(key);
|
|
97
|
-
result.set(key, param);
|
|
98
110
|
});
|
|
99
111
|
}
|
|
100
112
|
|
|
@@ -103,7 +115,7 @@ module.exports = function(core) {
|
|
|
103
115
|
const paramInfo = tracker.getData(params[key]);
|
|
104
116
|
if (!paramInfo) return;
|
|
105
117
|
|
|
106
|
-
const event = getPropagationEvent(params, paramInfo, data);
|
|
118
|
+
const event = getPropagationEvent(params, paramInfo.tags, data, [paramInfo]);
|
|
107
119
|
if (!event) return;
|
|
108
120
|
|
|
109
121
|
Object.assign(paramInfo, event);
|
|
@@ -167,7 +179,6 @@ module.exports = function(core) {
|
|
|
167
179
|
|
|
168
180
|
if (Object.keys(finalTags).length) {
|
|
169
181
|
const event = createPropagationEvent({
|
|
170
|
-
args: [],
|
|
171
182
|
context: `${inspect(params)}.toString()`,
|
|
172
183
|
moduleName: 'url',
|
|
173
184
|
methodName: 'URLSearchParams.toString',
|
|
@@ -62,7 +62,9 @@ module.exports = function(core) {
|
|
|
62
62
|
name: 'url.URL',
|
|
63
63
|
moduleName: 'url',
|
|
64
64
|
methodName: 'URL',
|
|
65
|
-
context
|
|
65
|
+
get context() {
|
|
66
|
+
return `url.URL('${strInfo.value}')`;
|
|
67
|
+
},
|
|
66
68
|
object: {
|
|
67
69
|
value: 'url',
|
|
68
70
|
tracked: false
|
|
@@ -78,7 +80,6 @@ module.exports = function(core) {
|
|
|
78
80
|
target: 'R',
|
|
79
81
|
stacktraceOpts: {
|
|
80
82
|
constructorOpt: data.hooked,
|
|
81
|
-
prependFrames: [data.orig]
|
|
82
83
|
},
|
|
83
84
|
});
|
|
84
85
|
}
|
|
@@ -40,7 +40,7 @@ module.exports = function(core) {
|
|
|
40
40
|
patchType,
|
|
41
41
|
usePerf: 'sync',
|
|
42
42
|
post(data) {
|
|
43
|
-
const { args, result, hooked
|
|
43
|
+
const { args, result, hooked } = data;
|
|
44
44
|
if (!result || !args[0] || !isString(args[0]) || !getPropagatorContext()) return;
|
|
45
45
|
|
|
46
46
|
let idx = 0;
|
|
@@ -114,7 +114,9 @@ module.exports = function(core) {
|
|
|
114
114
|
name,
|
|
115
115
|
moduleName: 'util',
|
|
116
116
|
methodName: 'format',
|
|
117
|
-
context
|
|
117
|
+
get context() {
|
|
118
|
+
return `util.format(${eventArgs.map((arg) => `'${arg.value}'`)})`;
|
|
119
|
+
},
|
|
118
120
|
object: {
|
|
119
121
|
value: 'util',
|
|
120
122
|
tracked: false
|
|
@@ -130,7 +132,6 @@ module.exports = function(core) {
|
|
|
130
132
|
target: 'R',
|
|
131
133
|
stacktraceOpts: {
|
|
132
134
|
constructorOpt: hooked,
|
|
133
|
-
prependFrames: [orig]
|
|
134
135
|
},
|
|
135
136
|
});
|
|
136
137
|
|
|
@@ -104,7 +104,9 @@ module.exports = function (core) {
|
|
|
104
104
|
if (isArgVulnerable) {
|
|
105
105
|
const event = createSinkEvent({
|
|
106
106
|
name: 'eval',
|
|
107
|
-
context
|
|
107
|
+
get context() {
|
|
108
|
+
return `eval('${strInfo.value}')`;
|
|
109
|
+
},
|
|
108
110
|
history: [strInfo],
|
|
109
111
|
object: {
|
|
110
112
|
value: 'global',
|
|
@@ -113,10 +113,9 @@ module.exports = function (core) {
|
|
|
113
113
|
});
|
|
114
114
|
const event = createSinkEvent({
|
|
115
115
|
name,
|
|
116
|
-
context
|
|
117
|
-
args.map((a) => a.inspectedValue),
|
|
118
|
-
|
|
119
|
-
)})`,
|
|
116
|
+
get context() {
|
|
117
|
+
return `${name}(${ArrayPrototypeJoin.call(args.map((a) => a.inspectedValue), ', ')})`;
|
|
118
|
+
},
|
|
120
119
|
history: [strInfo],
|
|
121
120
|
object: {
|
|
122
121
|
value: 'global.ContrastMethods',
|
|
@@ -105,7 +105,9 @@ module.exports = function (core) {
|
|
|
105
105
|
|
|
106
106
|
const sinkEvent = createSinkEvent({
|
|
107
107
|
args,
|
|
108
|
-
context
|
|
108
|
+
get context() {
|
|
109
|
+
return `marsdb.Collection.${method}(${args.map((a) => a.value)})`;
|
|
110
|
+
},
|
|
109
111
|
moduleName: 'marsdb',
|
|
110
112
|
methodName: `Collection.prototype.${method}`,
|
|
111
113
|
history: [strInfo],
|
|
@@ -337,7 +337,9 @@ module.exports = function (core) {
|
|
|
337
337
|
const resultVal = args[args.length - 1].value.startsWith('[Function') ? '' : 'Promise';
|
|
338
338
|
const sinkEvent = createSinkEvent({
|
|
339
339
|
args,
|
|
340
|
-
context
|
|
340
|
+
get context() {
|
|
341
|
+
return `${objName}.${method}(${args.map((a, idx) => isString(origArgs[idx]) ? `'${a.value}'` : a.value)})`;
|
|
342
|
+
},
|
|
341
343
|
history: [vulnInfo.strInfo],
|
|
342
344
|
object: {
|
|
343
345
|
tracked: false,
|
|
@@ -26,7 +26,6 @@ const {
|
|
|
26
26
|
Rule: { SQL_INJECTION: ruleId },
|
|
27
27
|
isString,
|
|
28
28
|
} = require('@contrast/common');
|
|
29
|
-
const { createModuleLabel } = require('../../propagation/common');
|
|
30
29
|
const { patchType, filterSafeTags } = require('../common');
|
|
31
30
|
|
|
32
31
|
const safeTags = [
|
|
@@ -75,10 +74,12 @@ module.exports = function (core) {
|
|
|
75
74
|
name,
|
|
76
75
|
moduleName: 'mssql',
|
|
77
76
|
methodName: `${obj}.prototype.${method}`,
|
|
78
|
-
context
|
|
77
|
+
get context() {
|
|
78
|
+
return `mssql.${obj}.${method}('${strInfo.value}')`;
|
|
79
|
+
},
|
|
79
80
|
history: [strInfo],
|
|
80
81
|
object: {
|
|
81
|
-
value: `
|
|
82
|
+
value: `mssql.${obj}`,
|
|
82
83
|
tracked: false,
|
|
83
84
|
},
|
|
84
85
|
args: [
|
|
@@ -91,7 +91,9 @@ module.exports = function(core) {
|
|
|
91
91
|
name: `${module}/${file}`,
|
|
92
92
|
moduleName: module,
|
|
93
93
|
methodName: `prototype.${method}`,
|
|
94
|
-
context
|
|
94
|
+
get context() {
|
|
95
|
+
return `${module}.${method}(${inspect(data.args[0])})`;
|
|
96
|
+
},
|
|
95
97
|
history: [strInfo],
|
|
96
98
|
object: {
|
|
97
99
|
value: `${module}.${obj}`,
|
|
@@ -186,7 +186,9 @@ module.exports = function(core) {
|
|
|
186
186
|
const { tags, args } = getAdjustedValues(data.args, vulns, vulnArgIdx);
|
|
187
187
|
const sinkEvent = createSinkEvent({
|
|
188
188
|
args,
|
|
189
|
-
context
|
|
189
|
+
get context() {
|
|
190
|
+
return `res.redirect(${ArrayPrototypeJoin.call(args.map((a) => a.value))})`;
|
|
191
|
+
},
|
|
190
192
|
history,
|
|
191
193
|
tags,
|
|
192
194
|
source: 'P0',
|
|
@@ -74,10 +74,12 @@ module.exports = function(core) {
|
|
|
74
74
|
name,
|
|
75
75
|
moduleName: 'sqlite3',
|
|
76
76
|
methodName: `Database.prototype.${method}`,
|
|
77
|
-
context
|
|
77
|
+
get context() {
|
|
78
|
+
return `db.${method}('${strInfo.value}')`;
|
|
79
|
+
},
|
|
78
80
|
history: [strInfo],
|
|
79
81
|
object: {
|
|
80
|
-
value: '
|
|
82
|
+
value: 'sqlite3.Database',
|
|
81
83
|
tracked: false,
|
|
82
84
|
},
|
|
83
85
|
args: [
|
|
@@ -205,10 +205,12 @@ module.exports = function (core) {
|
|
|
205
205
|
if (vulnerableArg) {
|
|
206
206
|
const event = createSinkEvent({
|
|
207
207
|
name,
|
|
208
|
-
context
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
208
|
+
get context() {
|
|
209
|
+
return `${name}(${ArrayPrototypeJoin.call(
|
|
210
|
+
argsInfo.map((a) => a.ctxValue),
|
|
211
|
+
', '
|
|
212
|
+
)})`;
|
|
213
|
+
},
|
|
212
214
|
history: [vulnerableArg.strInfo],
|
|
213
215
|
object: {
|
|
214
216
|
value: methodPath.includes('prototype')
|
|
@@ -19,6 +19,7 @@ const {
|
|
|
19
19
|
InputType,
|
|
20
20
|
DataflowTag,
|
|
21
21
|
isString,
|
|
22
|
+
empties,
|
|
22
23
|
primordials: {
|
|
23
24
|
ArrayPrototypeJoin,
|
|
24
25
|
StringPrototypeToLowerCase
|
|
@@ -43,8 +44,6 @@ module.exports = Core.makeComponent({
|
|
|
43
44
|
|
|
44
45
|
const logger = core.logger.child({ name: 'contrast:sources' });
|
|
45
46
|
|
|
46
|
-
const emptyStack = Object.freeze([]);
|
|
47
|
-
|
|
48
47
|
sources.createTags = function createTags({ inputType, fieldName = '', value, tagNames }) {
|
|
49
48
|
if (!value?.length) {
|
|
50
49
|
return null;
|
|
@@ -70,7 +69,7 @@ module.exports = Core.makeComponent({
|
|
|
70
69
|
|
|
71
70
|
sources.createStacktrace = function(stacktraceOpts) {
|
|
72
71
|
return config.assess.stacktraces === 'NONE' || config.assess.stacktraces === 'SINK'
|
|
73
|
-
?
|
|
72
|
+
? empties.ARRAY
|
|
74
73
|
: createSnapshot(stacktraceOpts)();
|
|
75
74
|
};
|
|
76
75
|
|
|
@@ -36,14 +36,14 @@ module.exports = function (core) {
|
|
|
36
36
|
patchType,
|
|
37
37
|
post({ result: server, funcKey }) {
|
|
38
38
|
server.addHook('preValidation', function preValidationHandler(request, reply, done) {
|
|
39
|
+
const sourceContext = getSourceContext();
|
|
40
|
+
if (!sourceContext) return done();
|
|
41
|
+
|
|
39
42
|
const bodyType = request?.headers?.['content-type']?.includes('/json')
|
|
40
43
|
? InputType.JSON_VALUE
|
|
41
44
|
: typeof request.body == 'object'
|
|
42
45
|
? InputType.PARAMETER_VALUE
|
|
43
46
|
: InputType.BODY;
|
|
44
|
-
const sourceContext = getSourceContext();
|
|
45
|
-
|
|
46
|
-
if (!sourceContext) return;
|
|
47
47
|
|
|
48
48
|
[
|
|
49
49
|
{ key: 'query', inputType: InputType.QUERYSTRING, alreadyTrackedFlag: 'parsedQuery' },
|
|
@@ -71,7 +71,7 @@ module.exports = function (core) {
|
|
|
71
71
|
}
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
done();
|
|
74
|
+
return done();
|
|
75
75
|
});
|
|
76
76
|
},
|
|
77
77
|
}));
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
'use strict';
|
|
16
16
|
|
|
17
|
-
const { empties, primordials: { StringPrototypeSplit } } = require('@contrast/common');
|
|
17
|
+
const { empties, primordials: { StringPrototypeSplit, StringPrototypeSubstr } } = require('@contrast/common');
|
|
18
18
|
|
|
19
19
|
//
|
|
20
20
|
// This module implements tag range manipulation functions. There are generally
|
|
@@ -536,6 +536,19 @@ function getAdjustedUntrackedValue(origValue) {
|
|
|
536
536
|
return origValue?.constructor?.name ?? (origValue === null ? 'null' : typeof origValue);
|
|
537
537
|
}
|
|
538
538
|
|
|
539
|
+
/**
|
|
540
|
+
* Truncation spec: https://github.com/Contrast-Security-Inc/assess-specifications/blob/master/vulnerability/truncate-event-snapshots.md
|
|
541
|
+
* While the spec calls to truncate the middle of strings, we're going to just chop off the end.
|
|
542
|
+
* This way we don't have to recalculate all of the tag ranges to adjust for truncating.
|
|
543
|
+
* @param {string} str input string to be truncated
|
|
544
|
+
* @param {number} len
|
|
545
|
+
* @returns {string}
|
|
546
|
+
*/
|
|
547
|
+
function truncateStringValue(str, len = 103) {
|
|
548
|
+
if (str.length <= len) return str;
|
|
549
|
+
return `${StringPrototypeSubstr.call(str, 0, len)}...`;
|
|
550
|
+
}
|
|
551
|
+
|
|
539
552
|
module.exports = {
|
|
540
553
|
createSubsetTags,
|
|
541
554
|
createAppendTags,
|
|
@@ -546,4 +559,5 @@ module.exports = {
|
|
|
546
559
|
createOverlappingTags,
|
|
547
560
|
createEscapeTagRanges,
|
|
548
561
|
getAdjustedUntrackedValue,
|
|
562
|
+
truncateStringValue,
|
|
549
563
|
};
|
package/lib/dataflow/tracker.js
CHANGED
|
@@ -37,10 +37,6 @@ module.exports = function tracker(core) {
|
|
|
37
37
|
return objMap.get(value) || null;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
function isTracked(value) {
|
|
41
|
-
return distringuish.isExternal(value);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
40
|
function track(value, metadata) {
|
|
45
41
|
let ret = Object.create(null);
|
|
46
42
|
|
|
@@ -152,6 +148,5 @@ module.exports = function tracker(core) {
|
|
|
152
148
|
untrack,
|
|
153
149
|
getData,
|
|
154
150
|
getInfo: getData,
|
|
155
|
-
isTracked,
|
|
156
151
|
};
|
|
157
152
|
};
|
package/lib/event-factory.js
CHANGED
|
@@ -45,7 +45,7 @@ module.exports = Core.makeComponent({
|
|
|
45
45
|
|
|
46
46
|
eventFactory.createdEvents = new WeakSet();
|
|
47
47
|
|
|
48
|
-
eventFactory.createSourceEvent = function(data
|
|
48
|
+
eventFactory.createSourceEvent = function(data) {
|
|
49
49
|
if (!data.result?.value) {
|
|
50
50
|
logger.debug(SOURCE_EVENT_MSG, `invalid result: ${data.name}`);
|
|
51
51
|
return null;
|
|
@@ -59,7 +59,6 @@ module.exports = function (core) {
|
|
|
59
59
|
value: displayArg
|
|
60
60
|
}],
|
|
61
61
|
context: `fastifyCookie(${displayArg})`,
|
|
62
|
-
history: [],
|
|
63
62
|
name: 'fastifyCookie',
|
|
64
63
|
moduleName: '@fastify/cookie',
|
|
65
64
|
methodName: '',
|
|
@@ -71,8 +70,6 @@ module.exports = function (core) {
|
|
|
71
70
|
tracked: false,
|
|
72
71
|
},
|
|
73
72
|
source: 'P0',
|
|
74
|
-
stack: [],
|
|
75
|
-
tags: {},
|
|
76
73
|
framework: '@fastify/cookie',
|
|
77
74
|
});
|
|
78
75
|
|
|
@@ -72,7 +72,6 @@ module.exports = function (core) {
|
|
|
72
72
|
value: displayArg
|
|
73
73
|
}],
|
|
74
74
|
context: `ctx.cookies.set(${displayArg})`,
|
|
75
|
-
history: [],
|
|
76
75
|
name: 'koaCookie',
|
|
77
76
|
moduleName: 'koa',
|
|
78
77
|
methodName: '',
|
|
@@ -84,8 +83,6 @@ module.exports = function (core) {
|
|
|
84
83
|
tracked: false,
|
|
85
84
|
},
|
|
86
85
|
source: 'P',
|
|
87
|
-
stack: [],
|
|
88
|
-
tags: {},
|
|
89
86
|
framework: 'koa',
|
|
90
87
|
});
|
|
91
88
|
if (!httpOnly) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/assess",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.54.1",
|
|
4
4
|
"description": "Contrast service providing framework-agnostic Assess support",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
|
|
@@ -21,16 +21,16 @@
|
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"@contrast/common": "1.32.0",
|
|
24
|
-
"@contrast/config": "1.
|
|
25
|
-
"@contrast/core": "1.
|
|
26
|
-
"@contrast/dep-hooks": "1.
|
|
24
|
+
"@contrast/config": "1.46.0",
|
|
25
|
+
"@contrast/core": "1.51.0",
|
|
26
|
+
"@contrast/dep-hooks": "1.20.0",
|
|
27
27
|
"@contrast/distringuish": "^5.1.0",
|
|
28
|
-
"@contrast/instrumentation": "1.
|
|
29
|
-
"@contrast/logger": "1.
|
|
30
|
-
"@contrast/patcher": "1.
|
|
31
|
-
"@contrast/rewriter": "1.
|
|
32
|
-
"@contrast/route-coverage": "1.
|
|
33
|
-
"@contrast/scopes": "1.
|
|
28
|
+
"@contrast/instrumentation": "1.30.0",
|
|
29
|
+
"@contrast/logger": "1.24.0",
|
|
30
|
+
"@contrast/patcher": "1.23.0",
|
|
31
|
+
"@contrast/rewriter": "1.27.0",
|
|
32
|
+
"@contrast/route-coverage": "1.42.0",
|
|
33
|
+
"@contrast/scopes": "1.21.0",
|
|
34
34
|
"semver": "^7.6.0"
|
|
35
35
|
}
|
|
36
36
|
}
|