@contrast/protect 1.15.1 → 1.17.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.
|
@@ -115,44 +115,15 @@ module.exports = function(core) {
|
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
function install() {
|
|
118
|
-
[{
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
moduleName: 'https'
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
moduleName: 'spdy'
|
|
126
|
-
},
|
|
127
|
-
{
|
|
128
|
-
moduleName: 'http2',
|
|
129
|
-
patchObjectsProps: [
|
|
130
|
-
{
|
|
131
|
-
methods: ['createServer', 'createSecureServer'],
|
|
132
|
-
patchType,
|
|
133
|
-
patchObjects: [
|
|
134
|
-
{
|
|
135
|
-
name: 'Server.prototype',
|
|
136
|
-
methods: ['emit'],
|
|
137
|
-
patchType,
|
|
138
|
-
around
|
|
139
|
-
}
|
|
140
|
-
]
|
|
141
|
-
}
|
|
142
|
-
]
|
|
143
|
-
}].forEach(({ moduleName, patchObjectsProps }) => {
|
|
144
|
-
const patchObjects = patchObjectsProps || [
|
|
145
|
-
{
|
|
118
|
+
['http', 'https', 'spdy', 'http2'].forEach((moduleName) => {
|
|
119
|
+
instrument({
|
|
120
|
+
moduleName,
|
|
121
|
+
patchObjects: [{
|
|
146
122
|
name: 'Server.prototype',
|
|
147
123
|
methods: ['emit'],
|
|
148
124
|
patchType,
|
|
149
125
|
around
|
|
150
|
-
}
|
|
151
|
-
];
|
|
152
|
-
|
|
153
|
-
instrument({
|
|
154
|
-
moduleName,
|
|
155
|
-
patchObjects
|
|
126
|
+
}]
|
|
156
127
|
});
|
|
157
128
|
});
|
|
158
129
|
}
|
|
@@ -29,8 +29,8 @@ module.exports = (core) => {
|
|
|
29
29
|
|
|
30
30
|
messages.on(Event.SERVER_SETTINGS_UPDATE, (serverUpdate) => {
|
|
31
31
|
const now = new Date().getTime();
|
|
32
|
-
const updatedIpAllowList = serverUpdate.
|
|
33
|
-
const updatedIpDenyList = serverUpdate.
|
|
32
|
+
const updatedIpAllowList = serverUpdate.protect?.rules?.ip_allowlist?.map?.((ipEntry) => ipEntryMap(ipEntry, now));
|
|
33
|
+
const updatedIpDenyList = serverUpdate.protect?.rules?.ip_denylist?.map?.((ipEntry) => ipEntryMap(ipEntry, now));
|
|
34
34
|
|
|
35
35
|
if (updatedIpAllowList) {
|
|
36
36
|
ipAllowlist.length = 0;
|
|
@@ -26,7 +26,7 @@ module.exports = (core) => {
|
|
|
26
26
|
const virtualPatchesEvaluators = inputAnalysis.virtualPatchesEvaluators = [];
|
|
27
27
|
|
|
28
28
|
messages.on(Event.SERVER_SETTINGS_UPDATE, (serverUpdate) => {
|
|
29
|
-
const virtualPatches = serverUpdate.
|
|
29
|
+
const virtualPatches = serverUpdate.protect?.['virtual-patches'];
|
|
30
30
|
if (virtualPatches) {
|
|
31
31
|
buildVPEvaluators(virtualPatches, virtualPatchesEvaluators);
|
|
32
32
|
}
|
package/lib/policy.js
CHANGED
|
@@ -112,8 +112,9 @@ module.exports = function(core) {
|
|
|
112
112
|
function readModeFromSetting(remoteSetting) {
|
|
113
113
|
switch (remoteSetting.mode) {
|
|
114
114
|
case 'OFF': return OFF;
|
|
115
|
-
case '
|
|
116
|
-
case '
|
|
115
|
+
case 'MONITOR': return MONITOR;
|
|
116
|
+
case 'BLOCK': return BLOCK;
|
|
117
|
+
case 'BLOCK_AT_PERIMETER': return BLOCK_AT_PERIMETER;
|
|
117
118
|
}
|
|
118
119
|
}
|
|
119
120
|
|
|
@@ -133,17 +134,16 @@ module.exports = function(core) {
|
|
|
133
134
|
* @param {[]} protectionRules
|
|
134
135
|
*/
|
|
135
136
|
function updateFromProtectionRules(protectionRules) {
|
|
136
|
-
for (const
|
|
137
|
-
const { id: ruleId } = remoteSetting;
|
|
137
|
+
for (const ruleId in protectionRules) {
|
|
138
138
|
if (ruleId === 'nosql-injection' && !getModeFromConfig('nosql-injection-mongo')) {
|
|
139
|
-
policy['nosql-injection-mongo'] = readModeFromSetting(
|
|
139
|
+
policy['nosql-injection-mongo'] = readModeFromSetting(protectionRules[ruleId]);
|
|
140
140
|
}
|
|
141
141
|
|
|
142
142
|
if (getModeFromConfig(ruleId)) {
|
|
143
143
|
continue;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
policy[ruleId] = readModeFromSetting(
|
|
146
|
+
policy[ruleId] && (policy[ruleId] = readModeFromSetting(protectionRules[ruleId]));
|
|
147
147
|
|
|
148
148
|
}
|
|
149
149
|
}
|
|
@@ -253,14 +253,12 @@ module.exports = function(core) {
|
|
|
253
253
|
function updateGlobalPolicy(remoteSettings) {
|
|
254
254
|
let update;
|
|
255
255
|
|
|
256
|
-
const protectionRules = remoteSettings?.
|
|
256
|
+
const protectionRules = remoteSettings?.protect?.rules;
|
|
257
257
|
if (protectionRules) {
|
|
258
258
|
updateFromProtectionRules(protectionRules);
|
|
259
259
|
update = 'application-settings';
|
|
260
|
-
}
|
|
261
260
|
|
|
262
|
-
|
|
263
|
-
const bbEnabled = remoteSettings.features.defend[BOT_BLOCKER];
|
|
261
|
+
const bbEnabled = remoteSettings.protect.rules?.bot_blocker?.enable;
|
|
264
262
|
|
|
265
263
|
if (
|
|
266
264
|
bbEnabled != null &&
|
|
@@ -268,30 +266,30 @@ module.exports = function(core) {
|
|
|
268
266
|
!config.protect.rules?.[BOT_BLOCKER]?.mode
|
|
269
267
|
) {
|
|
270
268
|
policy[BOT_BLOCKER] = bbEnabled ? BLOCK_AT_PERIMETER : OFF;
|
|
271
|
-
update = 'server-features';
|
|
272
269
|
}
|
|
273
270
|
}
|
|
274
271
|
|
|
275
272
|
if (update) {
|
|
276
273
|
updateRulesMask();
|
|
274
|
+
protect.policy.exclusions = compiled;
|
|
277
275
|
logger.info({ policy: protect.policy }, `protect policy updated from ${update}`);
|
|
278
276
|
}
|
|
279
277
|
}
|
|
280
278
|
|
|
281
279
|
function updateExclusions(serverUpdate) {
|
|
282
280
|
const exclusions = [
|
|
283
|
-
...(serverUpdate
|
|
284
|
-
...(serverUpdate
|
|
281
|
+
...(serverUpdate?.exclusions?.input || []),
|
|
282
|
+
...(serverUpdate?.exclusions?.url || [])
|
|
285
283
|
].filter((exclusion) => exclusion.modes.includes('defend'));
|
|
286
284
|
|
|
287
285
|
if (!exclusions.length) return;
|
|
288
286
|
compiled = initCompiled();
|
|
289
287
|
|
|
290
288
|
for (const exclusionDtm of exclusions) {
|
|
291
|
-
exclusionDtm.
|
|
289
|
+
exclusionDtm.type = exclusionDtm.type || 'URL';
|
|
292
290
|
|
|
293
|
-
const { name,
|
|
294
|
-
const key =
|
|
291
|
+
const { name, protect_rules, urls, type } = exclusionDtm;
|
|
292
|
+
const key = type.toLowerCase();
|
|
295
293
|
|
|
296
294
|
if (!compiled[key]) continue;
|
|
297
295
|
|
|
@@ -299,15 +297,15 @@ module.exports = function(core) {
|
|
|
299
297
|
const e = { name };
|
|
300
298
|
e.matchesUriPath = createUriPathMatcher(urls);
|
|
301
299
|
|
|
302
|
-
if (
|
|
303
|
-
e.matchesInputName = createInputNameMatcher(
|
|
300
|
+
if (name) {
|
|
301
|
+
e.matchesInputName = createInputNameMatcher(name);
|
|
304
302
|
}
|
|
305
303
|
|
|
306
|
-
if (
|
|
304
|
+
if (protect_rules.length) {
|
|
307
305
|
let rulesMask = 0;
|
|
308
306
|
const exclusionPolicy = {};
|
|
309
307
|
|
|
310
|
-
for (let ruleId of
|
|
308
|
+
for (let ruleId of protect_rules) {
|
|
311
309
|
// todo: this doesn't seem to make a difference?
|
|
312
310
|
if (ruleId === 'nosql-injection') {
|
|
313
311
|
ruleId = 'nosql-injection-mongo';
|
|
@@ -315,7 +313,7 @@ module.exports = function(core) {
|
|
|
315
313
|
|
|
316
314
|
if (agentLib.RuleType[ruleId]) {
|
|
317
315
|
Object.assign(exclusionPolicy, { [ruleId]: OFF });
|
|
318
|
-
if (
|
|
316
|
+
if (type === 'URL') {
|
|
319
317
|
rulesMask = rulesMask | agentLib.RuleType[ruleId];
|
|
320
318
|
exclusionPolicy.rulesMask = rulesMask;
|
|
321
319
|
}
|
|
@@ -345,8 +343,8 @@ module.exports = function(core) {
|
|
|
345
343
|
}
|
|
346
344
|
|
|
347
345
|
messages.on(SERVER_SETTINGS_UPDATE, (msg) => {
|
|
348
|
-
updateGlobalPolicy(msg);
|
|
349
346
|
updateExclusions(msg);
|
|
347
|
+
updateGlobalPolicy(msg);
|
|
350
348
|
});
|
|
351
349
|
|
|
352
350
|
initPolicy();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contrast/protect",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.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,9 +18,9 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"@contrast/agent-lib": "^5.3.4",
|
|
21
|
-
"@contrast/common": "1.
|
|
22
|
-
"@contrast/core": "1.
|
|
23
|
-
"@contrast/esm-hooks": "1.
|
|
21
|
+
"@contrast/common": "1.8.0",
|
|
22
|
+
"@contrast/core": "1.15.0",
|
|
23
|
+
"@contrast/esm-hooks": "1.11.0",
|
|
24
24
|
"@contrast/scopes": "1.3.0",
|
|
25
25
|
"ipaddr.js": "^2.0.1",
|
|
26
26
|
"semver": "^7.3.7"
|