@contrast/agent 4.7.0 → 4.7.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/bin/VERSION +1 -1
- package/bin/linux/contrast-service +0 -0
- package/bin/mac/contrast-service +0 -0
- package/bin/windows/contrast-service.exe +0 -0
- package/lib/assess/membrane/deserialization-membrane.js +4 -5
- package/lib/assess/membrane/source-membrane.js +15 -19
- package/lib/assess/models/call-context.js +1 -1
- package/lib/assess/policy/propagators.json +8 -0
- package/lib/assess/policy/rules.json +2 -2
- package/lib/assess/policy/signatures.json +27 -0
- package/lib/assess/policy/util.js +2 -1
- package/lib/assess/propagators/JSON/parse.js +1 -1
- package/lib/assess/propagators/JSON/stringify.js +3 -3
- package/lib/assess/propagators/array-prototype-join.js +7 -8
- package/lib/assess/propagators/common.js +7 -5
- package/lib/assess/propagators/handlebars-escape-expresssion.js +1 -1
- package/lib/assess/propagators/joi/boolean.js +1 -1
- package/lib/assess/propagators/joi/expression.js +1 -1
- package/lib/assess/propagators/joi/number.js +1 -1
- package/lib/assess/propagators/joi/string-base.js +1 -1
- package/lib/assess/propagators/joi/string-schema.js +12 -13
- package/lib/assess/propagators/joi/values.js +11 -11
- package/lib/assess/propagators/manager.js +12 -10
- package/lib/assess/propagators/mongoose/helpers.js +20 -0
- package/lib/assess/propagators/mongoose/index.js +18 -0
- package/lib/assess/propagators/mongoose/map.js +74 -0
- package/lib/assess/propagators/mongoose/string.js +104 -0
- package/lib/assess/propagators/number.js +54 -0
- package/lib/assess/propagators/object.js +6 -7
- package/lib/assess/propagators/path/basename.js +14 -13
- package/lib/assess/propagators/path/common.js +1 -1
- package/lib/assess/propagators/path/dirname.js +14 -13
- package/lib/assess/propagators/path/extname.js +14 -13
- package/lib/assess/propagators/path/parse.js +1 -1
- package/lib/assess/propagators/path/relative.js +7 -5
- package/lib/assess/propagators/querystring/escape.js +20 -18
- package/lib/assess/propagators/querystring/parse.js +7 -5
- package/lib/assess/propagators/querystring/stringify.js +25 -24
- package/lib/assess/propagators/querystring/unescape.js +20 -18
- package/lib/assess/propagators/sequelize/sql-string-escape.js +1 -1
- package/lib/assess/propagators/sequelize/sql-string-format-named-parameters.js +1 -1
- package/lib/assess/propagators/sequelize/sql-string-format.js +3 -3
- package/lib/assess/propagators/sequelize/utils.js +2 -2
- package/lib/assess/propagators/string-prototype-replace.js +30 -28
- package/lib/assess/propagators/string-prototype-split.js +36 -36
- package/lib/assess/propagators/string-prototype-trim.js +15 -17
- package/lib/assess/propagators/string.js +12 -16
- package/lib/assess/propagators/template-escape.js +21 -18
- package/lib/assess/propagators/templates.js +8 -8
- package/lib/assess/propagators/url/url-prototype-parse.js +5 -6
- package/lib/assess/propagators/url/url-url.js +51 -43
- package/lib/assess/propagators/util/format.js +1 -1
- package/lib/assess/propagators/v8/init-hooks.js +3 -3
- package/lib/assess/propagators/validator/init-hooks.js +22 -22
- package/lib/assess/sinks/common.js +10 -5
- package/lib/assess/sinks/libxmljs-xxe.js +1 -1
- package/lib/assess/sinks/mongodb.js +2 -1
- package/lib/assess/sinks/ssrf-url.js +1 -1
- package/lib/constants.js +4 -1
- package/lib/core/config/options.js +1 -1
- package/lib/core/rewrite/injections.js +8 -0
- package/lib/feature-set.js +1 -1
- package/lib/hooks/object-to-primitive.js +6 -7
- package/lib/hooks/patcher.js +1 -1
- package/lib/protect/rules/nosqli/nosql-injection-rule.js +228 -0
- package/lib/protect/rules/rule-factory.js +2 -2
- package/lib/protect/service.js +23 -11
- package/lib/protect/sinks/mongodb.js +56 -55
- package/lib/reporter/translations/to-protobuf/dtm/index.js +1 -1
- package/lib/reporter/translations/to-protobuf/dtm/ip-denylist-details.js +1 -1
- package/lib/reporter/translations/to-protobuf/dtm/rasp-rule-sample.js +1 -1
- package/lib/reporter/translations/to-protobuf/settings/defend-features.js +8 -6
- package/lib/reporter/translations/to-protobuf/settings/exclusions.js +5 -4
- package/lib/tracker.js +13 -65
- package/package.json +2 -1
- package/lib/protect/rules/nosqli/no-sql-injection-rule.js +0 -109
package/bin/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.28.
|
|
1
|
+
2.28.5
|
|
Binary file
|
package/bin/mac/contrast-service
CHANGED
|
Binary file
|
|
Binary file
|
|
@@ -58,19 +58,18 @@ class DeserializationMembrane extends Membrane {
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
const tracked = tracker.track(str);
|
|
61
|
-
const strData = tracker.getData(tracked);
|
|
62
61
|
|
|
63
|
-
if (!
|
|
62
|
+
if (!tracked) {
|
|
64
63
|
return str;
|
|
65
64
|
}
|
|
66
65
|
|
|
67
|
-
|
|
66
|
+
tracked.props.event = event;
|
|
68
67
|
event.parents.push(this.event);
|
|
69
|
-
|
|
68
|
+
tracked.props.tagRanges = this.tagRanges.map(
|
|
70
69
|
(t) => new TagRange(0, str.length - 1, t.tag)
|
|
71
70
|
);
|
|
72
71
|
|
|
73
|
-
return tracked;
|
|
72
|
+
return tracked.str;
|
|
74
73
|
}
|
|
75
74
|
}
|
|
76
75
|
|
|
@@ -13,7 +13,6 @@ Copyright: 2021 Contrast Security, Inc
|
|
|
13
13
|
way not consistent with the End User License Agreement.
|
|
14
14
|
*/
|
|
15
15
|
'use strict';
|
|
16
|
-
const _ = require('lodash');
|
|
17
16
|
|
|
18
17
|
const logger = require('../../core/logger')('contrast:source-membrane');
|
|
19
18
|
const Membrane = require('./index');
|
|
@@ -64,9 +63,7 @@ module.exports = class SourceMembrane extends Membrane {
|
|
|
64
63
|
if (cfg.array_request_sampling) {
|
|
65
64
|
this.sample = cfg.array_request_sampling.enable;
|
|
66
65
|
this.sampleThreshold = cfg.array_request_sampling.threshold;
|
|
67
|
-
this.sampleInterval =
|
|
68
|
-
? cfg.array_request_sampling.interval
|
|
69
|
-
: 1;
|
|
66
|
+
this.sampleInterval = cfg.array_request_sampling.interval || 1;
|
|
70
67
|
}
|
|
71
68
|
// used when a reqSourceEvent must be created because an entire object
|
|
72
69
|
// is being stringified but individual properties are not being referenced
|
|
@@ -139,7 +136,7 @@ module.exports = class SourceMembrane extends Membrane {
|
|
|
139
136
|
if (!this.ensureMetadata(metadata)) {
|
|
140
137
|
return str;
|
|
141
138
|
}
|
|
142
|
-
const tracked = tracker.
|
|
139
|
+
const tracked = tracker.track(str);
|
|
143
140
|
if (!tracked) {
|
|
144
141
|
return str;
|
|
145
142
|
}
|
|
@@ -355,11 +352,6 @@ module.exports = class SourceMembrane extends Membrane {
|
|
|
355
352
|
wrapArray(arr, metadata) {
|
|
356
353
|
metadata.isArray = true;
|
|
357
354
|
|
|
358
|
-
// if not sampling, treat it as any object. not sampling has 100%
|
|
359
|
-
// accuracy.
|
|
360
|
-
if (!this.sample) {
|
|
361
|
-
return super.wrapArray(arr, metadata);
|
|
362
|
-
}
|
|
363
355
|
// don't sample more than once
|
|
364
356
|
if (this.wrappedArrays.has(arr)) {
|
|
365
357
|
return arr;
|
|
@@ -367,16 +359,20 @@ module.exports = class SourceMembrane extends Membrane {
|
|
|
367
359
|
|
|
368
360
|
const limit = Math.min(this.sampleThreshold, arr.length);
|
|
369
361
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
362
|
+
// if not sampling, treat it as any object. not sampling has 100% accuracy.
|
|
363
|
+
if (!this.sample || (limit === arr.length && this.sampleInterval === 1)) {
|
|
364
|
+
return super.wrapObject(arr, metadata);
|
|
365
|
+
} else if (!this.sampleThreshold) {
|
|
366
|
+
return arr;
|
|
367
|
+
} else {
|
|
368
|
+
const origPath = metadata.path;
|
|
369
|
+
for (let i = 0; i < limit; i += this.sampleInterval) {
|
|
370
|
+
if (arr[i]) {
|
|
371
|
+
const m = Object.assign({}, metadata);
|
|
372
|
+
m.path = origPath ? `${origPath}[${i}]` : `[${i}]`;
|
|
373
|
+
const wrapped = this.wrap(arr[i], m);
|
|
374
|
+
arr[i] = wrapped;
|
|
377
375
|
}
|
|
378
|
-
|
|
379
|
-
arr[i] = this.wrap(arr[i], m);
|
|
380
376
|
}
|
|
381
377
|
}
|
|
382
378
|
|
|
@@ -40,10 +40,18 @@
|
|
|
40
40
|
"enabled": true,
|
|
41
41
|
"override": "./propagators/JSON/parse.js"
|
|
42
42
|
},
|
|
43
|
+
"mongoose": {
|
|
44
|
+
"enabled": true,
|
|
45
|
+
"override": "./propagators/mongoose"
|
|
46
|
+
},
|
|
43
47
|
"String": {
|
|
44
48
|
"enabled": true,
|
|
45
49
|
"override": "./propagators/string.js"
|
|
46
50
|
},
|
|
51
|
+
"Number": {
|
|
52
|
+
"enabled": true,
|
|
53
|
+
"override": "./propagators/number.js"
|
|
54
|
+
},
|
|
47
55
|
"Object": {
|
|
48
56
|
"enabled": true,
|
|
49
57
|
"override": "./propagators/object.js"
|
|
@@ -1157,7 +1157,7 @@
|
|
|
1157
1157
|
"args": [
|
|
1158
1158
|
{
|
|
1159
1159
|
"index": 0,
|
|
1160
|
-
"disallowedTags": ["limited-chars", "alphanum-space-hyphen"],
|
|
1160
|
+
"disallowedTags": ["limited-chars", "alphanum-space-hyphen", "custom-validated-nosql-injection"],
|
|
1161
1161
|
"requiredTags": ["untrusted"]
|
|
1162
1162
|
}
|
|
1163
1163
|
]
|
|
@@ -1172,7 +1172,7 @@
|
|
|
1172
1172
|
"args": [
|
|
1173
1173
|
{
|
|
1174
1174
|
"index": 0,
|
|
1175
|
-
"disallowedTags": [],
|
|
1175
|
+
"disallowedTags": ["custom-validated-nosql-injection"],
|
|
1176
1176
|
"requiredTags": ["untrusted"]
|
|
1177
1177
|
}
|
|
1178
1178
|
]
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
"methodName": "domainToUnicode",
|
|
21
21
|
"isModule": true
|
|
22
22
|
},
|
|
23
|
+
"template strings": {
|
|
24
|
+
"moduleName": "global",
|
|
25
|
+
"methodName": "ContrastMethods.__contrastTag",
|
|
26
|
+
"isModule": false
|
|
27
|
+
},
|
|
23
28
|
"axios": {
|
|
24
29
|
"moduleName": "axios",
|
|
25
30
|
"methodName": "",
|
|
@@ -642,6 +647,11 @@
|
|
|
642
647
|
"methodName": "toNamespacedPath",
|
|
643
648
|
"isModule": true
|
|
644
649
|
},
|
|
650
|
+
"path.normalize": {
|
|
651
|
+
"moduleName": "path",
|
|
652
|
+
"methodName": "normalize",
|
|
653
|
+
"isModule": true
|
|
654
|
+
},
|
|
645
655
|
"util.format": {
|
|
646
656
|
"moduleName": "util",
|
|
647
657
|
"methodName": "format",
|
|
@@ -1308,6 +1318,18 @@
|
|
|
1308
1318
|
"methodName": "string.domain",
|
|
1309
1319
|
"isModule": true
|
|
1310
1320
|
},
|
|
1321
|
+
"mongoose.string.doValidateSync": {
|
|
1322
|
+
"moduleName": "mongoose",
|
|
1323
|
+
"version": ">=5.0.0",
|
|
1324
|
+
"methodName": "mongoose.string.doValidateSync",
|
|
1325
|
+
"isModule": true
|
|
1326
|
+
},
|
|
1327
|
+
"mongoose.map.doValidateSync": {
|
|
1328
|
+
"moduleName": "mongoose",
|
|
1329
|
+
"version": ">=5.0.0",
|
|
1330
|
+
"methodName": "mongoose.map.doValidateSync",
|
|
1331
|
+
"isModule": true
|
|
1332
|
+
},
|
|
1311
1333
|
"v8.deserialize.serialize": {
|
|
1312
1334
|
"moduleName": "v8",
|
|
1313
1335
|
"methodName": "deserialize.serialize",
|
|
@@ -1322,6 +1344,11 @@
|
|
|
1322
1344
|
"moduleName": "dustjs-linkedin",
|
|
1323
1345
|
"methodName": "pipe",
|
|
1324
1346
|
"isModule": true
|
|
1347
|
+
},
|
|
1348
|
+
"Number": {
|
|
1349
|
+
"moduleName": "Number",
|
|
1350
|
+
"methodName": "isNaN",
|
|
1351
|
+
"isModule": false
|
|
1325
1352
|
}
|
|
1326
1353
|
}
|
|
1327
1354
|
}
|
|
@@ -89,6 +89,7 @@ utils.isRuleEnabled = function(ruleId) {
|
|
|
89
89
|
* @param {boolean} enabled What to set the enabled property to
|
|
90
90
|
*/
|
|
91
91
|
utils.setEnabled = function(node, enabled) {
|
|
92
|
+
/*eslint no-prototype-builtins: "warn"*/
|
|
92
93
|
if (node.hasOwnProperty('enabled')) {
|
|
93
94
|
node.enabled = enabled;
|
|
94
95
|
return true;
|
|
@@ -236,7 +237,7 @@ utils.patchRecursive = function(obj, hookOptions, depth) {
|
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
239
|
} catch (e) {
|
|
239
|
-
logger.info(`unable to
|
|
240
|
+
logger.info(`unable to recursively patch ${e}`);
|
|
240
241
|
}
|
|
241
242
|
|
|
242
243
|
return obj;
|
|
@@ -41,7 +41,7 @@ module.exports.handle = function() {
|
|
|
41
41
|
name: ContrastJSON.name,
|
|
42
42
|
patchType: PATCH_TYPES.ASSESS_PROPAGATOR,
|
|
43
43
|
post(data) {
|
|
44
|
-
const props = tracker.
|
|
44
|
+
const props = tracker.getData(data.args[0]);
|
|
45
45
|
const { result } = data;
|
|
46
46
|
if (props && result) {
|
|
47
47
|
const membrane = new DeserializationMembrane(data, props);
|
|
@@ -64,7 +64,7 @@ function getUntrustedSpaceProps(space) {
|
|
|
64
64
|
}
|
|
65
65
|
// otherwise if the space string is tracked then the entire json output inherits
|
|
66
66
|
// the tracked string's tags.
|
|
67
|
-
const props = tracker.
|
|
67
|
+
const props = tracker.getData(space);
|
|
68
68
|
if (!props || props.tagRanges.length === 0) {
|
|
69
69
|
return null;
|
|
70
70
|
}
|
|
@@ -185,7 +185,7 @@ module.exports.handle = function() {
|
|
|
185
185
|
*/
|
|
186
186
|
function contrastReplacer(key, val) {
|
|
187
187
|
let isTracked = false;
|
|
188
|
-
const valProperties = tracker.
|
|
188
|
+
const valProperties = tracker.getData(val);
|
|
189
189
|
if (valProperties && valProperties.tagRanges.length) {
|
|
190
190
|
data.metadata.propagate = true;
|
|
191
191
|
isTracked = true;
|
|
@@ -256,7 +256,7 @@ module.exports.handle = function() {
|
|
|
256
256
|
}
|
|
257
257
|
}
|
|
258
258
|
|
|
259
|
-
const tracked = tracker.
|
|
259
|
+
const tracked = tracker.track(data.result);
|
|
260
260
|
if (!tracked) {
|
|
261
261
|
return data.result;
|
|
262
262
|
}
|
|
@@ -27,7 +27,7 @@ module.exports.handle = function handle(data) {
|
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
// this handles join()
|
|
30
|
+
// this handles join() and join(undefined)
|
|
31
31
|
const del = data.args[0] === undefined ? ',' : data.args[0];
|
|
32
32
|
|
|
33
33
|
const parentEvents = [];
|
|
@@ -38,7 +38,7 @@ module.exports.handle = function handle(data) {
|
|
|
38
38
|
|
|
39
39
|
let delimiterTracked = false;
|
|
40
40
|
|
|
41
|
-
if (delimiterProperties
|
|
41
|
+
if (delimiterProperties) {
|
|
42
42
|
delimiterTracked = true;
|
|
43
43
|
parentEvents.push(delimiterProperties.event);
|
|
44
44
|
delimiterTagRanges.push(...delimiterProperties.tagRanges);
|
|
@@ -56,21 +56,20 @@ module.exports.handle = function handle(data) {
|
|
|
56
56
|
|
|
57
57
|
if (delimiterTracked || elementTracked) {
|
|
58
58
|
const tracked = tracker.track(data.result);
|
|
59
|
-
|
|
60
|
-
if (!metadata.tracked) {
|
|
59
|
+
if (!tracked) {
|
|
61
60
|
return;
|
|
62
61
|
}
|
|
63
62
|
|
|
64
|
-
|
|
63
|
+
tracked.props.event = createEvent(
|
|
65
64
|
data,
|
|
66
65
|
resultTagRanges,
|
|
67
66
|
parentEvents,
|
|
68
67
|
delimiterTracked,
|
|
69
68
|
elementTracked
|
|
70
69
|
);
|
|
71
|
-
|
|
70
|
+
tracked.props.tagRanges = resultTagRanges;
|
|
72
71
|
|
|
73
|
-
data.result = tracked;
|
|
72
|
+
data.result = tracked.str;
|
|
74
73
|
}
|
|
75
74
|
};
|
|
76
75
|
|
|
@@ -98,7 +97,7 @@ function propagateArrayData(
|
|
|
98
97
|
const elem = array[i];
|
|
99
98
|
const elemProperties = tracker.getData(elem);
|
|
100
99
|
|
|
101
|
-
if (elem && elemProperties
|
|
100
|
+
if (elem && elemProperties) {
|
|
102
101
|
parentEvents.push(elemProperties.event);
|
|
103
102
|
|
|
104
103
|
targetData.elementTracked = true;
|
|
@@ -62,7 +62,7 @@ const escapeRegExp = (str) => {
|
|
|
62
62
|
*/
|
|
63
63
|
const addTagRangesWithOffset = (metadata, arg) => {
|
|
64
64
|
const argData = tracker.getData(arg);
|
|
65
|
-
if (argData
|
|
65
|
+
if (argData) {
|
|
66
66
|
tagRangeUtil.addAllWithOffsetInPlace(
|
|
67
67
|
metadata.tagRanges,
|
|
68
68
|
argData.tagRanges,
|
|
@@ -115,10 +115,12 @@ const createEvent = ({ tagRanges, method, parents }, data) => {
|
|
|
115
115
|
*/
|
|
116
116
|
const trackResult = (metadata, data) => {
|
|
117
117
|
if (metadata.tagRanges.length) {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
118
|
+
const tracked = tracker.track(data.result);
|
|
119
|
+
if (tracked) {
|
|
120
|
+
tracked.props.tagRanges = metadata.tagRanges;
|
|
121
|
+
tracked.props.event = createEvent(metadata, data);
|
|
122
|
+
data.result = tracked.str;
|
|
123
|
+
}
|
|
122
124
|
}
|
|
123
125
|
};
|
|
124
126
|
|
|
@@ -48,7 +48,7 @@ function patchUtilsExport(utilsExport) {
|
|
|
48
48
|
alwaysRun: true,
|
|
49
49
|
post(data) {
|
|
50
50
|
const trackData = tracker.getData(data.result);
|
|
51
|
-
if (trackData
|
|
51
|
+
if (trackData) {
|
|
52
52
|
trackData.tagRanges = tagRangeUtil.add(
|
|
53
53
|
trackData.tagRanges,
|
|
54
54
|
new TagRange(0, data.result.length - 1, 'html-encoded')
|
|
@@ -32,7 +32,7 @@ function instrumentJoiExpression(expression) {
|
|
|
32
32
|
patchType: ASSESS_PROPAGATOR,
|
|
33
33
|
post(data) {
|
|
34
34
|
const trackingData = tracker.getData(data.args[0]);
|
|
35
|
-
if (trackingData
|
|
35
|
+
if (trackingData && data.result._template) {
|
|
36
36
|
trackingData.tagRanges = tagRangeUtil.add(
|
|
37
37
|
trackingData.tagRanges,
|
|
38
38
|
new TagRange(0, data.args[0].length - 1, 'html-encoded')
|
|
@@ -37,7 +37,7 @@ function instrumentJoiString(string) {
|
|
|
37
37
|
patchType: ASSESS_PROPAGATOR,
|
|
38
38
|
post(data) {
|
|
39
39
|
const trackingData = tracker.getData(data.args[0]);
|
|
40
|
-
if (data.result === undefined && trackingData
|
|
40
|
+
if (data.result === undefined && trackingData) {
|
|
41
41
|
const { event } = trackingData;
|
|
42
42
|
trackingData.tagRanges = tagRangeUtil.add(
|
|
43
43
|
trackingData.tagRanges,
|
|
@@ -79,29 +79,28 @@ function reTrackCoercedValue(coerce, rule) {
|
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
const argContrastProperties = tracker.getData(args[0]);
|
|
82
|
-
if (!argContrastProperties
|
|
82
|
+
if (!argContrastProperties) {
|
|
83
83
|
return;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
|
-
const
|
|
87
|
-
const strContrastProperties = tracker.getData(str);
|
|
86
|
+
const tracked = tracker.track(result.value);
|
|
88
87
|
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
new TagRange(0, str.length - 1, 'untrusted')
|
|
88
|
+
if (tracked) {
|
|
89
|
+
tracked.props.tagRanges = tagRangeUtil.add(
|
|
90
|
+
tracked.props.tagRanges,
|
|
91
|
+
new TagRange(0, tracked.str.length - 1, 'untrusted')
|
|
93
92
|
);
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
tracked.props.event = createPropagationEvent({
|
|
96
95
|
data,
|
|
97
96
|
trackedArgsData: argContrastProperties,
|
|
98
|
-
tagRanges:
|
|
97
|
+
tagRanges: tracked.props.tagRanges,
|
|
99
98
|
target: 'R',
|
|
100
99
|
joiMethod: rule
|
|
101
100
|
});
|
|
102
|
-
}
|
|
103
101
|
|
|
104
|
-
|
|
102
|
+
data.result = { value: tracked.str };
|
|
103
|
+
}
|
|
105
104
|
}
|
|
106
105
|
});
|
|
107
106
|
}
|
|
@@ -120,13 +119,13 @@ function wrapRuleAsValidator(rules, rule, tagName) {
|
|
|
120
119
|
}
|
|
121
120
|
|
|
122
121
|
const argContrastProperties = tracker.getData(args[0]);
|
|
123
|
-
if (!argContrastProperties
|
|
122
|
+
if (!argContrastProperties) {
|
|
124
123
|
return;
|
|
125
124
|
}
|
|
126
125
|
|
|
127
126
|
const strContrastProperties = tracker.getData(result);
|
|
128
127
|
|
|
129
|
-
if (strContrastProperties
|
|
128
|
+
if (strContrastProperties) {
|
|
130
129
|
strContrastProperties.tagRanges = tagRangeUtil.add(
|
|
131
130
|
strContrastProperties.tagRanges,
|
|
132
131
|
new TagRange(0, result.length - 1, tagName)
|
|
@@ -41,7 +41,7 @@ function instrumentJoiValues(values) {
|
|
|
41
41
|
name: 'joi.values',
|
|
42
42
|
patchType: ASSESS_PROPAGATOR,
|
|
43
43
|
post(data) {
|
|
44
|
-
|
|
44
|
+
let {
|
|
45
45
|
args: [value],
|
|
46
46
|
result
|
|
47
47
|
} = data;
|
|
@@ -55,7 +55,7 @@ function instrumentJoiValues(values) {
|
|
|
55
55
|
handler(result.value, value, data);
|
|
56
56
|
} else if (_.isString(result.value)) {
|
|
57
57
|
// use case is .valid() - safe
|
|
58
|
-
tracker.untrack(result.value);
|
|
58
|
+
result.value = tracker.untrack(result.value) || result.value;
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
});
|
|
@@ -94,14 +94,14 @@ const handler = (resultValue, argValue, data) => {
|
|
|
94
94
|
*/
|
|
95
95
|
function getRefHandler(resolvedTrackData, refTrackData) {
|
|
96
96
|
// 4 Cases
|
|
97
|
-
if (!resolvedTrackData
|
|
98
|
-
if (!refTrackData
|
|
97
|
+
if (!resolvedTrackData) {
|
|
98
|
+
if (!refTrackData) {
|
|
99
99
|
return null;
|
|
100
100
|
} else {
|
|
101
101
|
return handleRefOnlyTracked;
|
|
102
102
|
}
|
|
103
103
|
} else {
|
|
104
|
-
if (refTrackData
|
|
104
|
+
if (refTrackData) {
|
|
105
105
|
return handleBothTracked;
|
|
106
106
|
} else {
|
|
107
107
|
return handleTargetOnlyTracked;
|
|
@@ -131,7 +131,7 @@ function handleTargetOnlyTracked(data, resolvedTrackData, refTrackData) {
|
|
|
131
131
|
* @param {object} refTrackData tracking data for reference value
|
|
132
132
|
*/
|
|
133
133
|
function handleBothTracked(data, resolvedTrackData, refTrackData) {
|
|
134
|
-
|
|
134
|
+
let {
|
|
135
135
|
args: [value, , prefs],
|
|
136
136
|
result
|
|
137
137
|
} = data;
|
|
@@ -142,8 +142,8 @@ function handleBothTracked(data, resolvedTrackData, refTrackData) {
|
|
|
142
142
|
}
|
|
143
143
|
|
|
144
144
|
if (result.ref.map) {
|
|
145
|
-
tracker.untrack(data.result.value);
|
|
146
|
-
tracker.untrack(value);
|
|
145
|
+
data.result.value = tracker.untrack(data.result.value) || data.result.value;
|
|
146
|
+
value = tracker.untrack(value) || value;
|
|
147
147
|
} else {
|
|
148
148
|
copyValidationHistory(resolvedTrackData, refTrackData);
|
|
149
149
|
if (prefs.convert) {
|
|
@@ -160,7 +160,7 @@ function handleBothTracked(data, resolvedTrackData, refTrackData) {
|
|
|
160
160
|
* @param {object} refTrackData tracking data for reference value
|
|
161
161
|
*/
|
|
162
162
|
function handleRefOnlyTracked(data, resolvedTrackData, refTrackData) {
|
|
163
|
-
|
|
163
|
+
let {
|
|
164
164
|
args: [value, , prefs],
|
|
165
165
|
result
|
|
166
166
|
} = data;
|
|
@@ -179,8 +179,8 @@ function handleRefOnlyTracked(data, resolvedTrackData, refTrackData) {
|
|
|
179
179
|
} else {
|
|
180
180
|
// if map is used we can trust - like .valid()
|
|
181
181
|
if (result.ref.map) {
|
|
182
|
-
if (!tracker.getData(result.value)
|
|
183
|
-
tracker.untrack(value);
|
|
182
|
+
if (!tracker.getData(result.value)) {
|
|
183
|
+
value = tracker.untrack(value) || value;
|
|
184
184
|
}
|
|
185
185
|
} else {
|
|
186
186
|
logger.debug(
|
|
@@ -112,13 +112,14 @@ module.exports = function Propagator(agent, propagationDescriptor) {
|
|
|
112
112
|
|
|
113
113
|
// move the tags to the result of propagator
|
|
114
114
|
if (event.tagRanges.length > 0 && validTarget === data.result) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
115
|
+
const tracked = tracker.track(data.result);
|
|
116
|
+
if (tracked) {
|
|
117
|
+
tracked.props.tagRanges = event.tagRanges;
|
|
118
|
+
tracked.props.event = event;
|
|
119
|
+
data.result = tracked.str;
|
|
120
|
+
}
|
|
119
121
|
|
|
120
122
|
event.parents.push(...sourceEvents);
|
|
121
|
-
resultContrastProperties.event = event;
|
|
122
123
|
}
|
|
123
124
|
logger.trace('%s2%s %s --> %s', source, target, sources, [validTarget]);
|
|
124
125
|
};
|
|
@@ -206,7 +207,7 @@ function createAppendTagRanges(data) {
|
|
|
206
207
|
if (isString(data.obj)) {
|
|
207
208
|
offset = data.obj.length;
|
|
208
209
|
const sourceProps = tracker.getData(data.obj);
|
|
209
|
-
if (sourceProps
|
|
210
|
+
if (sourceProps) {
|
|
210
211
|
tagRangeUtil.addAllInPlace(newTags, sourceProps.tagRanges);
|
|
211
212
|
}
|
|
212
213
|
}
|
|
@@ -214,7 +215,7 @@ function createAppendTagRanges(data) {
|
|
|
214
215
|
for (const arg of data.args) {
|
|
215
216
|
if (arg) {
|
|
216
217
|
const props = tracker.getData(arg);
|
|
217
|
-
if (props
|
|
218
|
+
if (props) {
|
|
218
219
|
tagRangeUtil.addAllWithOffsetInPlace(newTags, props.tagRanges, offset);
|
|
219
220
|
}
|
|
220
221
|
|
|
@@ -339,7 +340,7 @@ function getSourcesMetadata(sources) {
|
|
|
339
340
|
function isSourceTracked(sourceName, source) {
|
|
340
341
|
if (source) {
|
|
341
342
|
const contrastProperties = tracker.getData(source);
|
|
342
|
-
return contrastProperties
|
|
343
|
+
return !!contrastProperties;
|
|
343
344
|
}
|
|
344
345
|
|
|
345
346
|
return false;
|
|
@@ -384,7 +385,7 @@ function getTrackedSources(sources, skipNested) {
|
|
|
384
385
|
function isTargetTracked(target, hasTags) {
|
|
385
386
|
if (hasTags) {
|
|
386
387
|
const contrastProperties = tracker.getData(target);
|
|
387
|
-
return contrastProperties
|
|
388
|
+
return !!contrastProperties;
|
|
388
389
|
}
|
|
389
390
|
|
|
390
391
|
return false;
|
|
@@ -457,7 +458,8 @@ function getValidSources(sources) {
|
|
|
457
458
|
const sourceContrastProperties = tracker.getData(source);
|
|
458
459
|
if (
|
|
459
460
|
isString(source) &&
|
|
460
|
-
!
|
|
461
|
+
(!sourceContrastProperties ||
|
|
462
|
+
(sourceContrastProperties && !sourceContrastProperties.tracked))
|
|
461
463
|
) {
|
|
462
464
|
return false;
|
|
463
465
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Copyright: 2021 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
|
+
const hasUserDefinedValidator = (data) =>
|
|
16
|
+
data.obj.validators.some((validator) => validator.type === 'user defined');
|
|
17
|
+
|
|
18
|
+
module.exports = {
|
|
19
|
+
hasUserDefinedValidator
|
|
20
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
Copyright: 2021 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
|
+
module.exports.handle = () => {
|
|
16
|
+
require('./map');
|
|
17
|
+
require('./string');
|
|
18
|
+
};
|