@contrast/protect 1.8.0 → 1.9.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/error-handlers/install/express4.js +3 -3
- package/lib/error-handlers/install/fastify.js +1 -1
- package/lib/error-handlers/install/hapi.js +1 -1
- package/lib/error-handlers/install/koa2.js +1 -1
- package/lib/hardening/handlers.js +9 -6
- package/lib/hardening/install/node-serialize0.js +5 -5
- package/lib/index.d.ts +5 -2
- package/lib/index.js +2 -2
- package/lib/input-analysis/handlers.js +26 -25
- package/lib/input-analysis/index.js +2 -2
- package/lib/input-analysis/install/http.js +0 -6
- package/lib/input-tracing/handlers/index.js +27 -16
- package/lib/input-tracing/index.js +2 -2
- package/lib/input-tracing/install/child-process.js +24 -24
- package/lib/input-tracing/install/eval.js +5 -5
- package/lib/input-tracing/install/fs.js +5 -5
- package/lib/input-tracing/install/function.js +6 -5
- package/lib/input-tracing/install/http.js +5 -5
- package/lib/input-tracing/install/mongodb.js +148 -160
- package/lib/input-tracing/install/mysql.js +5 -5
- package/lib/input-tracing/install/postgres.js +5 -5
- package/lib/input-tracing/install/sequelize.js +6 -5
- package/lib/input-tracing/install/sqlite3.js +5 -5
- package/lib/input-tracing/install/vm.js +25 -21
- package/lib/make-source-context.js +6 -23
- package/lib/policy.js +13 -8
- package/lib/semantic-analysis/handlers.js +20 -14
- package/lib/semantic-analysis/index.js +2 -5
- package/lib/semantic-analysis/install/libxmljs.js +5 -5
- package/lib/throw-security-exception.js +1 -3
- package/package.json +5 -5
|
@@ -20,7 +20,7 @@ const {
|
|
|
20
20
|
BLOCKING_MODES,
|
|
21
21
|
ProtectRuleMode: { OFF },
|
|
22
22
|
InputType,
|
|
23
|
-
|
|
23
|
+
traverseValues,
|
|
24
24
|
} = require('@contrast/common');
|
|
25
25
|
|
|
26
26
|
const {
|
|
@@ -38,22 +38,27 @@ const getRuleResults = function(obj, prop) {
|
|
|
38
38
|
// See files in protect/lib/input-tracing/install/.
|
|
39
39
|
|
|
40
40
|
module.exports = function(core) {
|
|
41
|
-
const { protect: { agentLib, semanticAnalysis, throwSecurityException } } = core;
|
|
41
|
+
const { protect: { agentLib, semanticAnalysis, throwSecurityException }, captureStacktrace } = core;
|
|
42
42
|
|
|
43
43
|
function handleResult(sourceContext, sinkContext, ruleId, mode, finding) {
|
|
44
|
+
const { value, stacktraceData } = sinkContext;
|
|
45
|
+
captureStacktrace(sinkContext, stacktraceData);
|
|
44
46
|
const result = {
|
|
45
47
|
blocked: false,
|
|
46
|
-
|
|
48
|
+
ruleId,
|
|
49
|
+
value,
|
|
50
|
+
mappedId: ruleId,
|
|
51
|
+
exploitMetadata: [{ command: value }],
|
|
47
52
|
sinkContext,
|
|
48
53
|
...finding
|
|
49
54
|
};
|
|
50
55
|
|
|
51
|
-
getRuleResults(sourceContext.
|
|
56
|
+
getRuleResults(sourceContext.resultsMap, ruleId).push(result);
|
|
52
57
|
|
|
53
58
|
if (BLOCKING_MODES.includes(mode)) {
|
|
54
59
|
result.blocked = true;
|
|
55
60
|
const blockInfo = [mode, ruleId];
|
|
56
|
-
sourceContext.
|
|
61
|
+
sourceContext.securityException = blockInfo;
|
|
57
62
|
throwSecurityException(sourceContext);
|
|
58
63
|
}
|
|
59
64
|
}
|
|
@@ -101,7 +106,7 @@ module.exports = function(core) {
|
|
|
101
106
|
|
|
102
107
|
if (agentLib.isDangerousPath(sinkContext.value, true)) {
|
|
103
108
|
handleResult(sourceContext, sinkContext, Rule.PATH_TRAVERSAL_SEMANTIC_FILE_SECURITY_BYPASS, mode, {
|
|
104
|
-
|
|
109
|
+
exploitMetadata: [{ path: sinkContext.value }]
|
|
105
110
|
});
|
|
106
111
|
}
|
|
107
112
|
};
|
|
@@ -113,7 +118,7 @@ module.exports = function(core) {
|
|
|
113
118
|
const findings = findExternalEntities(sinkContext.value);
|
|
114
119
|
if (findings.entities.length) {
|
|
115
120
|
handleResult(sourceContext, sinkContext, Rule.XXE, mode, {
|
|
116
|
-
findings,
|
|
121
|
+
exploitMetadata: [findings],
|
|
117
122
|
});
|
|
118
123
|
}
|
|
119
124
|
};
|
|
@@ -141,17 +146,15 @@ function findBackdoorInjection(sourceContext, command) {
|
|
|
141
146
|
[InputType.HEADER]: sourceContext.reqData.headers,
|
|
142
147
|
};
|
|
143
148
|
|
|
144
|
-
let found
|
|
149
|
+
let found;
|
|
145
150
|
for (const inputType in valuesOfInterest) {
|
|
151
|
+
if (found) break;
|
|
152
|
+
|
|
146
153
|
const values = valuesOfInterest[inputType];
|
|
147
154
|
|
|
148
155
|
if (values && Object.keys(values).length) {
|
|
149
|
-
|
|
150
|
-
if (
|
|
151
|
-
!found &&
|
|
152
|
-
type === 'Value' &&
|
|
153
|
-
isBackdoorDetected(value, command)
|
|
154
|
-
) {
|
|
156
|
+
traverseValues(values, (path, type, value, obj) => {
|
|
157
|
+
if (isBackdoorDetected(value, command)) {
|
|
155
158
|
let key;
|
|
156
159
|
if (inputType === InputType.HEADER) {
|
|
157
160
|
key = obj[path[0] - 1];
|
|
@@ -165,6 +168,9 @@ function findBackdoorInjection(sourceContext, command) {
|
|
|
165
168
|
path: path.slice(0, -1),
|
|
166
169
|
value: command
|
|
167
170
|
};
|
|
171
|
+
|
|
172
|
+
// halt traversal
|
|
173
|
+
return true;
|
|
168
174
|
}
|
|
169
175
|
});
|
|
170
176
|
}
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
'use strict';
|
|
17
17
|
|
|
18
|
-
const {
|
|
18
|
+
const { callChildComponentMethodsSync } = require('@contrast/common');
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* SEMANTIC ANALYSIS is a STAGE of Protect.
|
|
@@ -37,11 +37,8 @@ module.exports = function(core) {
|
|
|
37
37
|
require('./install/libxmljs')(core);
|
|
38
38
|
|
|
39
39
|
semanticAnalysis.install = function() {
|
|
40
|
-
|
|
40
|
+
callChildComponentMethodsSync(semanticAnalysis, 'install');
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
// There is no `.install()` method as this STAGE does not introduce side effects on its own,
|
|
44
|
-
// it uses the instrumentation that's already in place for INPUT TRACING.
|
|
45
|
-
|
|
46
43
|
return semanticAnalysis;
|
|
47
44
|
};
|
|
@@ -26,7 +26,6 @@ module.exports = function(core) {
|
|
|
26
26
|
logger,
|
|
27
27
|
protect: { semanticAnalysis },
|
|
28
28
|
protect,
|
|
29
|
-
captureStacktrace
|
|
30
29
|
} = core;
|
|
31
30
|
|
|
32
31
|
function install() {
|
|
@@ -60,10 +59,11 @@ module.exports = function(core) {
|
|
|
60
59
|
// see: https://help.semmle.com/wiki/display/JS/XML+external+entity+expansion
|
|
61
60
|
if (!sourceContext || !value || !isString(value) || !args[1].noent) return;
|
|
62
61
|
|
|
63
|
-
const sinkContext =
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
const sinkContext = {
|
|
63
|
+
name: 'libxmljs.parseXmlString',
|
|
64
|
+
value,
|
|
65
|
+
stacktraceData: { constructorOpt: hooked, prependFrames: [orig] },
|
|
66
|
+
};
|
|
67
67
|
|
|
68
68
|
try {
|
|
69
69
|
semanticAnalysis.handleXXE(sourceContext, sinkContext);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/protect",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.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)",
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@contrast/agent-lib": "^5.1.0",
|
|
21
|
-
"@contrast/common": "1.
|
|
22
|
-
"@contrast/core": "1.
|
|
23
|
-
"@contrast/esm-hooks": "1.
|
|
21
|
+
"@contrast/common": "1.2.0",
|
|
22
|
+
"@contrast/core": "1.8.0",
|
|
23
|
+
"@contrast/esm-hooks": "1.4.0",
|
|
24
24
|
"@contrast/scopes": "1.2.0",
|
|
25
25
|
"ipaddr.js": "^2.0.1",
|
|
26
26
|
"semver": "^7.3.7"
|
|
27
27
|
}
|
|
28
|
-
}
|
|
28
|
+
}
|