@contrast/protect 1.18.0 → 1.19.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.
|
@@ -692,7 +692,7 @@ module.exports = function(core) {
|
|
|
692
692
|
key: type === 'Key' ? value : path[path.length - 1],
|
|
693
693
|
value,
|
|
694
694
|
score: item.score,
|
|
695
|
-
idsList: [],
|
|
695
|
+
idsList: item.idsList || [],
|
|
696
696
|
};
|
|
697
697
|
if (item.mongoContext) {
|
|
698
698
|
result.mongoContext = item.mongoContext;
|
|
@@ -22,6 +22,7 @@ const {
|
|
|
22
22
|
isString,
|
|
23
23
|
traverseKeys,
|
|
24
24
|
traverseKeysAndValues,
|
|
25
|
+
agentLibIDListTypes
|
|
25
26
|
} = require('@contrast/common');
|
|
26
27
|
|
|
27
28
|
module.exports = function(core) {
|
|
@@ -127,10 +128,30 @@ module.exports = function(core) {
|
|
|
127
128
|
}
|
|
128
129
|
};
|
|
129
130
|
|
|
130
|
-
inputTracing.nosqlInjectionMongo = function(sourceContext, sinkContext) {
|
|
131
|
+
inputTracing.nosqlInjectionMongo = function (sourceContext, sinkContext) {
|
|
131
132
|
const ruleId = 'nosql-injection-mongo';
|
|
132
|
-
const
|
|
133
|
-
|
|
133
|
+
const nosqlInjectionMongoResults =
|
|
134
|
+
getResultsByRuleId(ruleId, sourceContext) || [];
|
|
135
|
+
const ssjsInjectionResults =
|
|
136
|
+
getResultsByRuleId('ssjs-injection', sourceContext) || [];
|
|
137
|
+
|
|
138
|
+
const stringInjectionResults = [...ssjsInjectionResults];
|
|
139
|
+
const expansionResults = [];
|
|
140
|
+
|
|
141
|
+
nosqlInjectionMongoResults.forEach((result) => {
|
|
142
|
+
if (
|
|
143
|
+
result.idsList &&
|
|
144
|
+
result.idsList.some(
|
|
145
|
+
(el) =>
|
|
146
|
+
el === agentLibIDListTypes.MONGO_SLEEP ||
|
|
147
|
+
el === agentLibIDListTypes.TRUE_CLAUSE_1
|
|
148
|
+
)
|
|
149
|
+
) {
|
|
150
|
+
stringInjectionResults.push(result);
|
|
151
|
+
} else {
|
|
152
|
+
expansionResults.push(result);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
134
155
|
|
|
135
156
|
if (expansionResults) {
|
|
136
157
|
let expansionFindings = null;
|
|
@@ -138,7 +159,13 @@ module.exports = function(core) {
|
|
|
138
159
|
expansionFindings = handleObjectValue(result, sinkContext.value);
|
|
139
160
|
|
|
140
161
|
if (expansionFindings) {
|
|
141
|
-
handleFindings(
|
|
162
|
+
handleFindings(
|
|
163
|
+
sourceContext,
|
|
164
|
+
sinkContext,
|
|
165
|
+
ruleId,
|
|
166
|
+
result,
|
|
167
|
+
expansionFindings
|
|
168
|
+
);
|
|
142
169
|
}
|
|
143
170
|
}
|
|
144
171
|
}
|
|
@@ -148,30 +175,44 @@ module.exports = function(core) {
|
|
|
148
175
|
|
|
149
176
|
for (const result of stringInjectionResults) {
|
|
150
177
|
if (typeof sinkContext.value === 'object') {
|
|
151
|
-
traverseKeysAndValues(
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
178
|
+
traverseKeysAndValues(
|
|
179
|
+
sinkContext.value,
|
|
180
|
+
function (path, type, value, obj) {
|
|
181
|
+
if (type !== 'Key' && !agentLib.isMongoQueryType(value)) return;
|
|
182
|
+
|
|
183
|
+
if (!stringFindings && type == 'Key' && value == '$accumulator') {
|
|
184
|
+
stringFindings =
|
|
185
|
+
handleStringValue(result, obj[value]?.init, agentLib) ||
|
|
186
|
+
handleStringValue(result, obj[value]?.merge, agentLib) ||
|
|
187
|
+
handleStringValue(result, obj[value]?.finalize, agentLib) ||
|
|
188
|
+
handleStringValue(result, obj[value]?.accumulate, agentLib);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if (!stringFindings && type == 'Key' && value == '$function') {
|
|
192
|
+
stringFindings = handleStringValue(
|
|
193
|
+
result,
|
|
194
|
+
obj['$function']?.body,
|
|
195
|
+
agentLib
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (!stringFindings) {
|
|
200
|
+
stringFindings = handleStringValue(
|
|
201
|
+
result,
|
|
202
|
+
obj[value],
|
|
203
|
+
agentLib
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (stringFindings) return true;
|
|
169
208
|
}
|
|
170
|
-
|
|
171
|
-
if (stringFindings) return true;
|
|
172
|
-
});
|
|
209
|
+
);
|
|
173
210
|
} else if (typeof sinkContext.value === 'string') {
|
|
174
|
-
stringFindings = handleStringValue(
|
|
211
|
+
stringFindings = handleStringValue(
|
|
212
|
+
result,
|
|
213
|
+
sinkContext.value,
|
|
214
|
+
agentLib
|
|
215
|
+
);
|
|
175
216
|
}
|
|
176
217
|
|
|
177
218
|
if (stringFindings) {
|
|
@@ -184,7 +225,13 @@ module.exports = function(core) {
|
|
|
184
225
|
sourceContext.resultsMap[ruleId] = [nosqlInjectionResult];
|
|
185
226
|
}
|
|
186
227
|
|
|
187
|
-
handleFindings(
|
|
228
|
+
handleFindings(
|
|
229
|
+
sourceContext,
|
|
230
|
+
sinkContext,
|
|
231
|
+
ruleId,
|
|
232
|
+
nosqlInjectionResult,
|
|
233
|
+
stringFindings
|
|
234
|
+
);
|
|
188
235
|
}
|
|
189
236
|
}
|
|
190
237
|
}
|
|
@@ -26,7 +26,7 @@ module.exports = function (core) {
|
|
|
26
26
|
|
|
27
27
|
function getCursorQueryData(args, version) {
|
|
28
28
|
const query = semver.gte(version, '3.3.0')
|
|
29
|
-
? args[0]?.cmd?.query
|
|
29
|
+
? args[0]?.cmd?.query || args[1]?.query
|
|
30
30
|
: args[1]?.query;
|
|
31
31
|
|
|
32
32
|
if (!query) {
|
|
@@ -67,12 +67,12 @@ module.exports = function (core) {
|
|
|
67
67
|
inputTracing.nosqlInjectionMongo(sourceContext, sinkContext);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
function
|
|
70
|
+
function CollectionVal({ args, ...ctx }) {
|
|
71
71
|
const value = typeof args[0] == 'function' ? null : args[0];
|
|
72
72
|
preHook(value, ctx);
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
function
|
|
75
|
+
function dbCommandVal({ args, ...ctx }) {
|
|
76
76
|
const value = args[0]?.filter;
|
|
77
77
|
preHook(value, ctx);
|
|
78
78
|
}
|
|
@@ -87,7 +87,7 @@ module.exports = function (core) {
|
|
|
87
87
|
preHook(value, ctx);
|
|
88
88
|
}
|
|
89
89
|
|
|
90
|
-
function
|
|
90
|
+
function firstArgVal({ args, ...ctx }) {
|
|
91
91
|
const value = args[0];
|
|
92
92
|
preHook(value, ctx);
|
|
93
93
|
}
|
|
@@ -106,16 +106,19 @@ module.exports = function (core) {
|
|
|
106
106
|
[
|
|
107
107
|
{
|
|
108
108
|
moduleName,
|
|
109
|
-
version: '>=4.0.0',
|
|
109
|
+
version: '>=2.0.0 <3.0.0 || >=4.0.0',
|
|
110
110
|
patchObjects: [
|
|
111
111
|
{
|
|
112
112
|
name: 'Collection.prototype',
|
|
113
113
|
methods: [
|
|
114
|
+
'update',
|
|
114
115
|
'updateOne',
|
|
115
116
|
'replaceOne',
|
|
116
117
|
'updateMany',
|
|
118
|
+
'remove',
|
|
117
119
|
'deleteOne',
|
|
118
120
|
'deleteMany',
|
|
121
|
+
'findAndModify',
|
|
119
122
|
'findOneAndDelete',
|
|
120
123
|
'findOneAndReplace',
|
|
121
124
|
'findOneAndUpdate',
|
|
@@ -125,13 +128,13 @@ module.exports = function (core) {
|
|
|
125
128
|
'aggregate'
|
|
126
129
|
],
|
|
127
130
|
patchType,
|
|
128
|
-
preHookFn:
|
|
131
|
+
preHookFn: CollectionVal
|
|
129
132
|
},
|
|
130
133
|
{
|
|
131
134
|
name: 'Db.prototype',
|
|
132
135
|
methods: ['command'],
|
|
133
136
|
patchType,
|
|
134
|
-
preHookFn:
|
|
137
|
+
preHookFn: dbCommandVal
|
|
135
138
|
}
|
|
136
139
|
]
|
|
137
140
|
},
|
|
@@ -157,18 +160,30 @@ module.exports = function (core) {
|
|
|
157
160
|
patchType,
|
|
158
161
|
preHookFn: v3CursorVal
|
|
159
162
|
},
|
|
163
|
+
{
|
|
164
|
+
name: 'Db.prototype',
|
|
165
|
+
methods: ['command'],
|
|
166
|
+
patchType,
|
|
167
|
+
preHookFn: dbCommandVal
|
|
168
|
+
},
|
|
160
169
|
{
|
|
161
170
|
name: 'Db.prototype',
|
|
162
171
|
methods: ['eval'],
|
|
163
172
|
patchType,
|
|
164
|
-
preHookFn:
|
|
165
|
-
}
|
|
173
|
+
preHookFn: firstArgVal
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: 'Collection.prototype',
|
|
177
|
+
methods: ['find'],
|
|
178
|
+
patchType,
|
|
179
|
+
preHookFn: firstArgVal
|
|
180
|
+
},
|
|
166
181
|
]
|
|
167
182
|
},
|
|
168
183
|
{
|
|
169
184
|
moduleName,
|
|
170
185
|
file: 'lib/topologies/topology_base.js',
|
|
171
|
-
version: '<4.0.0',
|
|
186
|
+
version: '<4.0.0 >=3.0.0',
|
|
172
187
|
patchObjects: [
|
|
173
188
|
{
|
|
174
189
|
name: 'TopologyBase.prototype',
|
|
@@ -187,7 +202,7 @@ module.exports = function (core) {
|
|
|
187
202
|
{
|
|
188
203
|
moduleName,
|
|
189
204
|
file: 'lib/topologies/native_topology.js',
|
|
190
|
-
version: '<4.0.0',
|
|
205
|
+
version: '<4.0.0 >=3.0.0',
|
|
191
206
|
patchObjects: [
|
|
192
207
|
{
|
|
193
208
|
name: 'NativeTopology.prototype',
|
|
@@ -204,7 +219,7 @@ module.exports = function (core) {
|
|
|
204
219
|
preHookFn: v3CursorVal
|
|
205
220
|
}
|
|
206
221
|
]
|
|
207
|
-
}
|
|
222
|
+
},
|
|
208
223
|
].forEach(({ moduleName, file, version, patchObjects }) => {
|
|
209
224
|
instrument({
|
|
210
225
|
moduleName,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/protect",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"description": "Contrast service providing framework-agnostic Protect support",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Contrast Security <nodejs@contrastsecurity.com> (https://www.contrastsecurity.com)",
|
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
"test": "../scripts/test.sh"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@contrast/agent-lib": "^
|
|
21
|
-
"@contrast/common": "1.
|
|
22
|
-
"@contrast/core": "1.
|
|
23
|
-
"@contrast/esm-hooks": "1.
|
|
24
|
-
"@contrast/scopes": "1.
|
|
20
|
+
"@contrast/agent-lib": "^7.0.1",
|
|
21
|
+
"@contrast/common": "1.10.0",
|
|
22
|
+
"@contrast/core": "1.17.0",
|
|
23
|
+
"@contrast/esm-hooks": "1.13.0",
|
|
24
|
+
"@contrast/scopes": "1.4.0",
|
|
25
25
|
"ipaddr.js": "^2.0.1",
|
|
26
26
|
"semver": "^7.3.7"
|
|
27
27
|
},
|