@contrast/assess 1.10.0 → 1.11.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 +1 -1
- package/lib/dataflow/index.js +1 -1
- 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 +1 -1
- package/lib/dataflow/propagation/install/JSON/stringify.js +1 -1
- package/lib/dataflow/propagation/install/array-prototype-join.js +1 -1
- package/lib/dataflow/propagation/install/buffer.js +1 -1
- package/lib/dataflow/propagation/install/contrast-methods/add.js +1 -1
- 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 +1 -1
- package/lib/dataflow/propagation/install/contrast-methods/tag.js +1 -1
- package/lib/dataflow/propagation/install/decode-uri-component.js +1 -1
- package/lib/dataflow/propagation/install/ejs/escape-xml.js +1 -1
- package/lib/dataflow/propagation/install/ejs/index.js +1 -1
- package/lib/dataflow/propagation/install/encode-uri-component.js +1 -1
- package/lib/dataflow/propagation/install/escape-html.js +1 -1
- package/lib/dataflow/propagation/install/escape.js +1 -1
- package/lib/dataflow/propagation/install/handlebars-utils-escape-expression.js +1 -1
- 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 -37
- package/lib/dataflow/propagation/install/mysql-connection-escape.js +1 -1
- package/lib/dataflow/propagation/install/parse-int.js +1 -1
- package/lib/dataflow/propagation/install/path/basename.js +1 -1
- 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 +1 -1
- package/lib/dataflow/propagation/install/path/normalize.js +1 -1
- package/lib/dataflow/propagation/install/pug/index.js +1 -1
- package/lib/dataflow/propagation/install/pug-runtime-escape.js +1 -1
- package/lib/dataflow/propagation/install/querystring/index.js +1 -1
- package/lib/dataflow/propagation/install/querystring/parse.js +1 -1
- package/lib/dataflow/propagation/install/reg-exp-prototype-exec.js +182 -0
- package/lib/dataflow/propagation/install/sequelize.js +1 -1
- package/lib/dataflow/propagation/install/sql-template-strings.js +1 -1
- package/lib/dataflow/propagation/install/string/concat.js +1 -1
- package/lib/dataflow/propagation/install/string/format-methods.js +1 -1
- package/lib/dataflow/propagation/install/string/html-methods.js +1 -1
- package/lib/dataflow/propagation/install/string/index.js +65 -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 +2 -2
- package/lib/dataflow/propagation/install/string/slice.js +1 -1
- package/lib/dataflow/propagation/install/string/split.js +1 -1
- package/lib/dataflow/propagation/install/string/substring.js +1 -1
- package/lib/dataflow/propagation/install/string/trim.js +1 -1
- package/lib/dataflow/propagation/install/unescape.js +1 -1
- package/lib/dataflow/propagation/install/url/domain-parsers.js +1 -1
- package/lib/dataflow/propagation/install/url/index.js +3 -1
- package/lib/dataflow/propagation/install/url/parse.js +131 -0
- package/lib/dataflow/propagation/install/url/searchParams.js +133 -0
- package/lib/dataflow/propagation/install/url/url.js +9 -52
- package/lib/dataflow/propagation/install/validator/hooks.js +1 -1
- 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 +1 -1
- package/lib/dataflow/sinks/install/eval.js +1 -1
- package/lib/dataflow/sinks/install/express/index.js +1 -1
- package/lib/dataflow/sinks/install/express/unvalidated-redirect.js +1 -1
- package/lib/dataflow/sinks/install/fastify/index.js +1 -1
- package/lib/dataflow/sinks/install/fastify/unvalidated-redirect.js +1 -1
- package/lib/dataflow/sinks/install/fs.js +1 -1
- package/lib/dataflow/sinks/install/function.js +1 -1
- package/lib/dataflow/sinks/install/http/index.js +1 -1
- package/lib/dataflow/sinks/install/http/request.js +1 -1
- package/lib/dataflow/sinks/install/http/server-response.js +1 -1
- package/lib/dataflow/sinks/install/koa/index.js +1 -1
- package/lib/dataflow/sinks/install/koa/unvalidated-redirect.js +1 -1
- package/lib/dataflow/sinks/install/marsdb.js +1 -1
- package/lib/dataflow/sinks/install/mongodb.js +31 -24
- package/lib/dataflow/sinks/install/mssql.js +1 -1
- package/lib/dataflow/sinks/install/mysql.js +1 -1
- package/lib/dataflow/sinks/install/postgres.js +1 -1
- package/lib/dataflow/sinks/install/sequelize.js +1 -1
- package/lib/dataflow/sinks/install/sqlite3.js +1 -1
- package/lib/dataflow/sinks/install/vm.js +1 -1
- package/lib/dataflow/sources/common.js +1 -1
- package/lib/dataflow/sources/handler.js +1 -1
- 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 +1 -1
- 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 +1 -1
- package/lib/dataflow/utils/is-safe-content-type.js +1 -1
- package/lib/dataflow/utils/is-vulnerable.js +1 -1
- package/lib/index.js +1 -1
- 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/index.js +1 -1
- package/lib/session-configuration/install/http.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,133 @@
|
|
|
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
|
+
|
|
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
|
+
dataflow: { tracker, eventFactory: { createPropagationEvent } }
|
|
28
|
+
}
|
|
29
|
+
} = core;
|
|
30
|
+
|
|
31
|
+
function getPropagationEvent(params, paramInfo, data) {
|
|
32
|
+
return createPropagationEvent({
|
|
33
|
+
name: 'url.URLSearchParams',
|
|
34
|
+
moduleName: 'url',
|
|
35
|
+
methodName: 'URLSearchParams',
|
|
36
|
+
context: `url.URLSearchParams('${inspect(params)}')`,
|
|
37
|
+
object: {
|
|
38
|
+
value: 'url',
|
|
39
|
+
tracked: false
|
|
40
|
+
},
|
|
41
|
+
result: {
|
|
42
|
+
value: inspect(data.result),
|
|
43
|
+
tracked: true
|
|
44
|
+
},
|
|
45
|
+
args: [{ value: inspect(params), tracked: false }],
|
|
46
|
+
tags: paramInfo.tags,
|
|
47
|
+
history: [paramInfo],
|
|
48
|
+
source: 'P',
|
|
49
|
+
target: 'R',
|
|
50
|
+
stacktraceOpts: {
|
|
51
|
+
constructorOpt: data.hooked,
|
|
52
|
+
prependFrames: [data.orig]
|
|
53
|
+
},
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return core.assess.dataflow.propagation.urlInstrumentation.searchParams = {
|
|
58
|
+
install() {
|
|
59
|
+
depHooks.resolve({ name: 'url' }, (url) => {
|
|
60
|
+
|
|
61
|
+
const name = 'url.URLSearchParams';
|
|
62
|
+
|
|
63
|
+
patcher.patch(url, 'URLSearchParams', {
|
|
64
|
+
name,
|
|
65
|
+
patchType,
|
|
66
|
+
post(data) {
|
|
67
|
+
const { args, obj, result } = data;
|
|
68
|
+
if (!result || !args[0] || !sources.getStore()?.assess || instrumentation.isLocked()) return;
|
|
69
|
+
|
|
70
|
+
const [params] = args;
|
|
71
|
+
|
|
72
|
+
if (isString(params)) {
|
|
73
|
+
params.split('&').forEach((query) => {
|
|
74
|
+
const startIdx = query.indexOf('?') + 1;
|
|
75
|
+
const endIdx = query.indexOf('=');
|
|
76
|
+
const key = query.substring(startIdx, endIdx);
|
|
77
|
+
const param = query.substring(endIdx + 1, query.length);
|
|
78
|
+
const paramInfo = tracker.getData(param);
|
|
79
|
+
if (!paramInfo) return;
|
|
80
|
+
|
|
81
|
+
const event = getPropagationEvent(params, paramInfo, data);
|
|
82
|
+
if (!event);
|
|
83
|
+
|
|
84
|
+
Object.assign(paramInfo, event);
|
|
85
|
+
const { extern } = paramInfo || tracker.track(param, event);
|
|
86
|
+
|
|
87
|
+
if (extern) {
|
|
88
|
+
result.set(key, extern);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (typeof params === 'object') {
|
|
94
|
+
Object.keys(params).forEach((key) => {
|
|
95
|
+
const paramInfo = tracker.getData(params[key]);
|
|
96
|
+
if (!paramInfo) return;
|
|
97
|
+
|
|
98
|
+
const event = getPropagationEvent(params, paramInfo, data);
|
|
99
|
+
if (!event) return;
|
|
100
|
+
|
|
101
|
+
Object.assign(paramInfo, event);
|
|
102
|
+
const { extern } = paramInfo || tracker.track(params[key], event);
|
|
103
|
+
|
|
104
|
+
if (extern) {
|
|
105
|
+
result.set(key, extern);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
patcher.patch(obj.prototype, 'toString', {
|
|
111
|
+
name: 'url.URLSearchParams.toString',
|
|
112
|
+
patchType,
|
|
113
|
+
post(data) {
|
|
114
|
+
const { obj: params } = data;
|
|
115
|
+
let i = 0;
|
|
116
|
+
let str = '';
|
|
117
|
+
params.forEach((val, key) => {
|
|
118
|
+
if (i === 0) {
|
|
119
|
+
str = key.concat('=', val);
|
|
120
|
+
} else {
|
|
121
|
+
str = str.concat('&', key, '=', val);
|
|
122
|
+
}
|
|
123
|
+
i++;
|
|
124
|
+
});
|
|
125
|
+
data.result = str;
|
|
126
|
+
}
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
};
|
|
@@ -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
|
|
|
@@ -42,7 +42,6 @@ module.exports = function(core) {
|
|
|
42
42
|
],
|
|
43
43
|
'pathname',
|
|
44
44
|
'search',
|
|
45
|
-
'searchParams',
|
|
46
45
|
'hash'
|
|
47
46
|
]
|
|
48
47
|
];
|
|
@@ -84,6 +83,7 @@ module.exports = function(core) {
|
|
|
84
83
|
return core.assess.dataflow.propagation.urlInstrumentation.url = {
|
|
85
84
|
install() {
|
|
86
85
|
depHooks.resolve({ name: 'url' }, (url) => {
|
|
86
|
+
const { URLSearchParams } = url;
|
|
87
87
|
const name = 'url.URL';
|
|
88
88
|
patcher.patch(url, 'URL', {
|
|
89
89
|
name,
|
|
@@ -116,33 +116,11 @@ module.exports = function(core) {
|
|
|
116
116
|
const strInfo = tracker.getData(url);
|
|
117
117
|
if (!strInfo) return;
|
|
118
118
|
|
|
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
119
|
const proxy = new Proxy(data.result, {
|
|
139
120
|
set(obj, prop, value) {
|
|
140
121
|
return Reflect.set(obj, prop, value);
|
|
141
122
|
},
|
|
142
123
|
get(obj, prop) {
|
|
143
|
-
if (prop === 'searchParams') {
|
|
144
|
-
return searchParamsProxy;
|
|
145
|
-
}
|
|
146
124
|
if (prop === 'toString' || prop === 'toJSON') {
|
|
147
125
|
return function() {
|
|
148
126
|
return Reflect.get(obj, '_contrast_href');
|
|
@@ -159,7 +137,7 @@ module.exports = function(core) {
|
|
|
159
137
|
const traverse = function(href, url, keys, idx = 0) {
|
|
160
138
|
let substr = href;
|
|
161
139
|
keys.forEach((key) => {
|
|
162
|
-
if (typeof key === 'string'
|
|
140
|
+
if (typeof key === 'string') {
|
|
163
141
|
const part = url[key];
|
|
164
142
|
if (part !== 'null') {
|
|
165
143
|
|
|
@@ -180,38 +158,13 @@ module.exports = function(core) {
|
|
|
180
158
|
const event = getPropagationEvent(strInfo, partInfo, data);
|
|
181
159
|
if (!event) return;
|
|
182
160
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
186
|
-
const { extern } = partInfo || tracker.track(part, event);
|
|
161
|
+
Object.assign(partInfo, event);
|
|
162
|
+
const { extern } = tracker.track(part, event);
|
|
187
163
|
|
|
188
164
|
if (extern) {
|
|
189
165
|
proxy[`_contrast_${key}`] = extern;
|
|
190
166
|
}
|
|
191
167
|
}
|
|
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
168
|
} else {
|
|
216
169
|
traverse(substr, url, key, 0);
|
|
217
170
|
}
|
|
@@ -219,6 +172,10 @@ module.exports = function(core) {
|
|
|
219
172
|
};
|
|
220
173
|
|
|
221
174
|
traverse(url, result, keys, 0);
|
|
175
|
+
|
|
176
|
+
if (proxy.search) {
|
|
177
|
+
proxy._contrast_searchParams = new URLSearchParams(proxy.search);
|
|
178
|
+
}
|
|
222
179
|
data.result = proxy;
|
|
223
180
|
}
|
|
224
181
|
});
|
|
@@ -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
|
|
|
@@ -85,16 +85,16 @@ module.exports = function(core) {
|
|
|
85
85
|
const instr = core.assess.dataflow.sinks.mongodb = {};
|
|
86
86
|
|
|
87
87
|
instr.getQueryVulnerabilityInfo = function getQueryVulnerabilityInfo(query) {
|
|
88
|
+
const reportSafe = [];
|
|
88
89
|
let vulnInfo = null;
|
|
89
|
-
let reportSafe = null;
|
|
90
90
|
|
|
91
91
|
if (isString(query)) {
|
|
92
92
|
const strInfo = tracker.getData(query);
|
|
93
93
|
if (strInfo) {
|
|
94
94
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
95
95
|
vulnInfo = { strInfo };
|
|
96
|
-
} else {
|
|
97
|
-
reportSafe
|
|
96
|
+
} else if (config.assess.safe_positives.enable) {
|
|
97
|
+
reportSafe.push({ strInfo });
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
100
|
|
|
@@ -109,8 +109,8 @@ module.exports = function(core) {
|
|
|
109
109
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
110
110
|
vulnInfo = { path: [...path], strInfo };
|
|
111
111
|
return true; // halts traversal
|
|
112
|
-
} else {
|
|
113
|
-
reportSafe
|
|
112
|
+
} else if (config.assess.safe_positives.enable) {
|
|
113
|
+
reportSafe.push({ path: [...path], strInfo });
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
});
|
|
@@ -119,8 +119,8 @@ module.exports = function(core) {
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
instr.getAggregateVulnerabilityInfo = function getAggregateVulnerabilityInfo(aggregation) {
|
|
122
|
+
const reportSafe = [];
|
|
122
123
|
let vulnInfo = null;
|
|
123
|
-
let reportSafe = null;
|
|
124
124
|
|
|
125
125
|
if (!isNonEmptyObject(aggregation)) return { vulnInfo, reportSafe };
|
|
126
126
|
|
|
@@ -141,8 +141,8 @@ module.exports = function(core) {
|
|
|
141
141
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
142
142
|
vulnInfo = { path: [...path], strInfo };
|
|
143
143
|
return true; // halts traversal
|
|
144
|
-
} else {
|
|
145
|
-
reportSafe
|
|
144
|
+
} else if (config.assess.safe_positives.enable) {
|
|
145
|
+
reportSafe.push({ path: [...path], strInfo });
|
|
146
146
|
}
|
|
147
147
|
}
|
|
148
148
|
}
|
|
@@ -152,16 +152,16 @@ module.exports = function(core) {
|
|
|
152
152
|
};
|
|
153
153
|
|
|
154
154
|
instr.getMapReduceVulnerabilityInfo = function getMapReduceVulnerabilityInfo(argToCheck, argIdx) {
|
|
155
|
+
const reportSafe = [];
|
|
155
156
|
let vulnInfo = null;
|
|
156
|
-
let reportSafe = null;
|
|
157
157
|
|
|
158
158
|
if (argIdx !== 2 && isString(argToCheck)) {
|
|
159
159
|
const strInfo = tracker.getData(argToCheck);
|
|
160
160
|
if (strInfo) {
|
|
161
161
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
162
162
|
vulnInfo = { strInfo };
|
|
163
|
-
} else {
|
|
164
|
-
reportSafe
|
|
163
|
+
} else if (config.assess.safe_positives.enable) {
|
|
164
|
+
reportSafe.push({ strInfo });
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
167
|
|
|
@@ -181,8 +181,8 @@ module.exports = function(core) {
|
|
|
181
181
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
182
182
|
vulnInfo = { path: [...path], strInfo };
|
|
183
183
|
return true; // halts traversal
|
|
184
|
-
} else {
|
|
185
|
-
reportSafe
|
|
184
|
+
} else if (config.assess.safe_positives.enable) {
|
|
185
|
+
reportSafe.push({ path: [...path], strInfo });
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
}
|
|
@@ -192,16 +192,16 @@ module.exports = function(core) {
|
|
|
192
192
|
};
|
|
193
193
|
|
|
194
194
|
instr.getGroupVulnerabilityInfo = function getGroupVulnerabilityInfo(argToCheck, argIdx) {
|
|
195
|
+
const reportSafe = [];
|
|
195
196
|
let vulnInfo = null;
|
|
196
|
-
let reportSafe = null;
|
|
197
197
|
|
|
198
198
|
if (argIdx !== 1 && isString(argToCheck)) {
|
|
199
199
|
const strInfo = tracker.getData(argToCheck);
|
|
200
200
|
if (strInfo) {
|
|
201
201
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
202
202
|
vulnInfo = { strInfo };
|
|
203
|
-
} else {
|
|
204
|
-
reportSafe
|
|
203
|
+
} else if (config.assess.safe_positives.enable) {
|
|
204
|
+
reportSafe.push({ strInfo });
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
|
@@ -216,8 +216,8 @@ module.exports = function(core) {
|
|
|
216
216
|
if (isVulnerable(UNTRUSTED, querySafeTags, strInfo.tags)) {
|
|
217
217
|
vulnInfo = { path: [...path], strInfo };
|
|
218
218
|
return true; // halts traversal
|
|
219
|
-
} else {
|
|
220
|
-
reportSafe
|
|
219
|
+
} else if (config.assess.safe_positives.enable) {
|
|
220
|
+
reportSafe.push({ path: [...path], strInfo });
|
|
221
221
|
}
|
|
222
222
|
}
|
|
223
223
|
});
|
|
@@ -248,12 +248,19 @@ module.exports = function(core) {
|
|
|
248
248
|
vulnArgIdx = argIdx;
|
|
249
249
|
break;
|
|
250
250
|
}
|
|
251
|
-
|
|
251
|
+
|
|
252
|
+
if (config.assess.safe_positives.enable && reportSafe.length) {
|
|
253
|
+
reportSafe.forEach(el => safeReports.push({ ...el, argIdx }));
|
|
254
|
+
}
|
|
252
255
|
}
|
|
253
256
|
|
|
254
257
|
if (!vulnInfo) {
|
|
255
258
|
if (safeReports.length && config.assess.safe_positives.enable) {
|
|
256
|
-
const safeTags = safeReports
|
|
259
|
+
const safeTags = safeReports
|
|
260
|
+
.map((report) => filterSafeTags(querySafeTags, report.strInfo))
|
|
261
|
+
.flat()
|
|
262
|
+
.filter((value, index, self) => index === self.indexOf(value));
|
|
263
|
+
|
|
257
264
|
const strInfo = safeReports.map((report) => {
|
|
258
265
|
const tags = report.path ? utils.createAdjustedQueryTags(report.path, report.strInfo.tags, report.strInfo.value, inspect(origArgs[report.argIdx], { depth: 4 })) : report.strInfo?.tags;
|
|
259
266
|
|
|
@@ -266,7 +273,7 @@ module.exports = function(core) {
|
|
|
266
273
|
reportSafePositive({
|
|
267
274
|
name,
|
|
268
275
|
ruleId: NOSQL_INJECTION_MONGO,
|
|
269
|
-
safeTags
|
|
276
|
+
safeTags,
|
|
270
277
|
strInfo: strInfo.length === 1 ? strInfo[0] : strInfo
|
|
271
278
|
});
|
|
272
279
|
}
|
|
@@ -323,8 +330,6 @@ module.exports = function(core) {
|
|
|
323
330
|
});
|
|
324
331
|
};
|
|
325
332
|
|
|
326
|
-
return instr;
|
|
327
|
-
|
|
328
333
|
function patchCollection(mongodb, version) {
|
|
329
334
|
for (const method of collectionMethods) {
|
|
330
335
|
const proto = mongodb.Collection.prototype;
|
|
@@ -400,4 +405,6 @@ module.exports = function(core) {
|
|
|
400
405
|
|
|
401
406
|
return name;
|
|
402
407
|
}
|
|
408
|
+
|
|
409
|
+
return instr;
|
|
403
410
|
};
|