@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
|
@@ -0,0 +1,74 @@
|
|
|
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
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const tracker = require('../../../tracker');
|
|
18
|
+
const patcher = require('../../../hooks/patcher');
|
|
19
|
+
const requireHook = require('../../../hooks/require');
|
|
20
|
+
const tagRangeUtil = require('../../models/tag-range/util');
|
|
21
|
+
const {
|
|
22
|
+
PATCH_TYPES: { ASSESS_PROPAGATOR }
|
|
23
|
+
} = require('../../../constants');
|
|
24
|
+
const TagRange = require('../../models/tag-range');
|
|
25
|
+
const { CallContext, PropagationEvent, Signature } = require('../../models');
|
|
26
|
+
const { hasUserDefinedValidator } = require('./helpers');
|
|
27
|
+
|
|
28
|
+
const doValidateSyncPatcher = (SchemaMap) => {
|
|
29
|
+
patcher.patch(SchemaMap.prototype, 'doValidateSync', {
|
|
30
|
+
alwaysRun: true,
|
|
31
|
+
name: 'mongoose.map.doValidateSync',
|
|
32
|
+
patchType: ASSESS_PROPAGATOR,
|
|
33
|
+
post(data) {
|
|
34
|
+
if (data.result || data.obj.options.of.name !== 'String') return;
|
|
35
|
+
|
|
36
|
+
if (!hasUserDefinedValidator(data)) return;
|
|
37
|
+
|
|
38
|
+
for (const value of data.args[0].values()) {
|
|
39
|
+
const trackingData = tracker.track(value);
|
|
40
|
+
|
|
41
|
+
if (!trackingData) return;
|
|
42
|
+
|
|
43
|
+
const { props } = trackingData;
|
|
44
|
+
const stringLength = value.length - 1;
|
|
45
|
+
|
|
46
|
+
props.tagRanges = tagRangeUtil.add(
|
|
47
|
+
props.tagRanges,
|
|
48
|
+
new TagRange(0, stringLength, 'custom-validated-nosql-injection')
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
props.tagRanges = tagRangeUtil.add(
|
|
52
|
+
props.tagRanges,
|
|
53
|
+
new TagRange(0, stringLength, 'string-type-checked')
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
props.event = new PropagationEvent({
|
|
57
|
+
context: new CallContext(data),
|
|
58
|
+
signature: new Signature('mongoose.map.doValidateSync'),
|
|
59
|
+
tagRanges: props.tagRanges,
|
|
60
|
+
source: 'P',
|
|
61
|
+
target: 'A',
|
|
62
|
+
parents: [props.event]
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
requireHook.resolve(
|
|
70
|
+
{ name: 'mongoose', file: 'lib/schema/map.js', version: '>=5.0.0' },
|
|
71
|
+
(SchemaMap) => {
|
|
72
|
+
doValidateSyncPatcher(SchemaMap);
|
|
73
|
+
}
|
|
74
|
+
);
|
|
@@ -0,0 +1,104 @@
|
|
|
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
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const tracker = require('../../../tracker');
|
|
18
|
+
const patcher = require('../../../hooks/patcher');
|
|
19
|
+
const requireHook = require('../../../hooks/require');
|
|
20
|
+
const tagRangeUtil = require('../../models/tag-range/util');
|
|
21
|
+
const {
|
|
22
|
+
PATCH_TYPES: { ASSESS_PROPAGATOR }
|
|
23
|
+
} = require('../../../constants');
|
|
24
|
+
const TagRange = require('../../models/tag-range');
|
|
25
|
+
const { CallContext, PropagationEvent, Signature } = require('../../models');
|
|
26
|
+
const { hasUserDefinedValidator } = require('./helpers');
|
|
27
|
+
|
|
28
|
+
const enumPatcher = (SchemaString) => {
|
|
29
|
+
patcher.patch(SchemaString.prototype, 'enum', {
|
|
30
|
+
alwaysRun: true,
|
|
31
|
+
name: 'mongoose.string.enum',
|
|
32
|
+
patchType: ASSESS_PROPAGATOR,
|
|
33
|
+
post(data) {
|
|
34
|
+
if (!data.result) return;
|
|
35
|
+
|
|
36
|
+
const enumValidator = data.result.validators.find(
|
|
37
|
+
(validator) => validator.type === 'enum'
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
if (!enumValidator) return;
|
|
41
|
+
|
|
42
|
+
patcher.patch(enumValidator, 'validator', {
|
|
43
|
+
alwaysRun: true,
|
|
44
|
+
name: 'mongoose.string.enumValidator',
|
|
45
|
+
patchType: ASSESS_PROPAGATOR,
|
|
46
|
+
post(data) {
|
|
47
|
+
if (!data.result) return;
|
|
48
|
+
|
|
49
|
+
tracker.untrack(data.args[0]);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
const doValidateSyncPatcher = (SchemaString) => {
|
|
57
|
+
patcher.patch(SchemaString.prototype, 'doValidateSync', {
|
|
58
|
+
alwaysRun: true,
|
|
59
|
+
name: 'mongoose.string.doValidateSync',
|
|
60
|
+
patchType: ASSESS_PROPAGATOR,
|
|
61
|
+
post(data) {
|
|
62
|
+
if (data.result) return;
|
|
63
|
+
|
|
64
|
+
if (!hasUserDefinedValidator(data)) return;
|
|
65
|
+
|
|
66
|
+
const trackingData = tracker.track(data.args[0]);
|
|
67
|
+
if (!trackingData) return;
|
|
68
|
+
|
|
69
|
+
const { props } = trackingData;
|
|
70
|
+
const incomingStringLength = data.args[0].length - 1;
|
|
71
|
+
|
|
72
|
+
props.tagRanges = tagRangeUtil.add(
|
|
73
|
+
props.tagRanges,
|
|
74
|
+
new TagRange(
|
|
75
|
+
0,
|
|
76
|
+
incomingStringLength,
|
|
77
|
+
'custom-validated-nosql-injection'
|
|
78
|
+
)
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
props.tagRanges = tagRangeUtil.add(
|
|
82
|
+
props.tagRanges,
|
|
83
|
+
new TagRange(0, incomingStringLength, 'string-type-checked')
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
props.event = new PropagationEvent({
|
|
87
|
+
context: new CallContext(data),
|
|
88
|
+
signature: new Signature('mongoose.string.doValidateSync'),
|
|
89
|
+
tagRanges: props.tagRanges,
|
|
90
|
+
source: 'P',
|
|
91
|
+
target: 'A',
|
|
92
|
+
parents: [props.event]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
requireHook.resolve(
|
|
99
|
+
{ name: 'mongoose', file: 'lib/schema/string.js', version: '>=5.0.0' },
|
|
100
|
+
(SchemaString) => {
|
|
101
|
+
enumPatcher(SchemaString);
|
|
102
|
+
doValidateSyncPatcher(SchemaString);
|
|
103
|
+
}
|
|
104
|
+
);
|
|
@@ -0,0 +1,54 @@
|
|
|
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
|
+
'use strict';
|
|
16
|
+
|
|
17
|
+
const tracker = require('../../tracker.js');
|
|
18
|
+
const patcher = require('../../hooks/patcher.js');
|
|
19
|
+
const { PATCH_TYPES } = require('../../constants');
|
|
20
|
+
const tagRangeUtil = require('../models/tag-range/util');
|
|
21
|
+
const TagRange = require('../models/tag-range');
|
|
22
|
+
const ContrastNumber = require('../../core/rewrite/injections').get('Number');
|
|
23
|
+
const { CallContext, PropagationEvent, Signature } = require('../models');
|
|
24
|
+
|
|
25
|
+
function handle() {
|
|
26
|
+
ContrastNumber.enable();
|
|
27
|
+
|
|
28
|
+
patcher.patch(ContrastNumber.value, {
|
|
29
|
+
name: 'Number',
|
|
30
|
+
patchType: PATCH_TYPES.ASSESS_PROPAGATOR,
|
|
31
|
+
post(data) {
|
|
32
|
+
const trackingData = tracker.getData(data.args[0]);
|
|
33
|
+
|
|
34
|
+
if (!Number.isNaN(data.result) && trackingData) {
|
|
35
|
+
const { event } = trackingData;
|
|
36
|
+
trackingData.tagRanges = tagRangeUtil.add(
|
|
37
|
+
trackingData.tagRanges,
|
|
38
|
+
new TagRange(0, data.args[0].length - 1, 'limited-chars')
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
trackingData.event = new PropagationEvent({
|
|
42
|
+
context: new CallContext(data),
|
|
43
|
+
signature: new Signature('Number'),
|
|
44
|
+
tagRanges: trackingData.tagRanges,
|
|
45
|
+
source: 'P',
|
|
46
|
+
target: 'P',
|
|
47
|
+
parents: [event]
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = { handle };
|
|
@@ -41,18 +41,17 @@ function handle() {
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const argContrastProperties = tracker.getData(arg);
|
|
44
|
-
if (!argContrastProperties
|
|
44
|
+
if (!argContrastProperties) {
|
|
45
45
|
return;
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
strContrastProperties.tagRanges = strContrastProperties.tagRanges.concat(
|
|
48
|
+
const tracked = tracker.track(data.result);
|
|
49
|
+
if (tracked) {
|
|
50
|
+
tracked.props.event = argContrastProperties.event;
|
|
51
|
+
tracked.props.tagRanges = tracked.props.tagRanges.concat(
|
|
53
52
|
argContrastProperties.tagRanges
|
|
54
53
|
);
|
|
55
|
-
data.result = str;
|
|
54
|
+
data.result = tracked.str;
|
|
56
55
|
}
|
|
57
56
|
}
|
|
58
57
|
});
|
|
@@ -45,7 +45,7 @@ module.exports.handle = function handle() {
|
|
|
45
45
|
if (!path || !data.result) return;
|
|
46
46
|
|
|
47
47
|
const trackingData = tracker.getData(path);
|
|
48
|
-
if (!trackingData
|
|
48
|
+
if (!trackingData) return;
|
|
49
49
|
|
|
50
50
|
if (extension) {
|
|
51
51
|
const extIndex = _path.lastIndexOf(extension);
|
|
@@ -68,19 +68,20 @@ module.exports.handle = function handle() {
|
|
|
68
68
|
// no tags propagated to the result
|
|
69
69
|
if (!tagRanges.length) return;
|
|
70
70
|
|
|
71
|
-
const result = tracker.track(data.result);
|
|
72
|
-
const resultData = tracker.getData(result);
|
|
73
71
|
const parentEvent = trackingData.event;
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
72
|
+
const tracked = tracker.track(data.result);
|
|
73
|
+
if (tracked) {
|
|
74
|
+
tracked.props.tagRanges = tagRanges;
|
|
75
|
+
tracked.props.event = new PropagationEvent({
|
|
76
|
+
context: new CallContext(data),
|
|
77
|
+
parents: [parentEvent],
|
|
78
|
+
signature,
|
|
79
|
+
source: 'P',
|
|
80
|
+
tagRanges,
|
|
81
|
+
target: 'R'
|
|
82
|
+
});
|
|
83
|
+
data.result = tracked.str;
|
|
84
|
+
}
|
|
84
85
|
}
|
|
85
86
|
});
|
|
86
87
|
}
|
|
@@ -333,7 +333,7 @@ function propagate({ resultMeta, data, win32 }) {
|
|
|
333
333
|
evaluator: (segmentOffset) => segmentOffset > -1,
|
|
334
334
|
offset: 0,
|
|
335
335
|
str: arg,
|
|
336
|
-
tagRanges: argData
|
|
336
|
+
tagRanges: argData ? argData.tagRanges : []
|
|
337
337
|
};
|
|
338
338
|
|
|
339
339
|
const targetTagRanges = adjustTagsToPart(
|
|
@@ -42,7 +42,7 @@ module.exports.handle = function handle() {
|
|
|
42
42
|
if (!data.args[0]) return;
|
|
43
43
|
|
|
44
44
|
const trackingData = tracker.getData(data.args[0]);
|
|
45
|
-
if (!trackingData
|
|
45
|
+
if (!trackingData) return;
|
|
46
46
|
|
|
47
47
|
// path.dirname() does a slice at 0 to the calculated end separator
|
|
48
48
|
const tagRanges = createSubsetTagRanges({
|
|
@@ -57,19 +57,20 @@ module.exports.handle = function handle() {
|
|
|
57
57
|
|
|
58
58
|
if (!tagRanges.length) return;
|
|
59
59
|
|
|
60
|
-
const
|
|
61
|
-
const resultData = tracker.getData(result);
|
|
60
|
+
const tracked = tracker.track(data.result);
|
|
62
61
|
const parentEvent = trackingData.event;
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
if (tracked) {
|
|
63
|
+
tracked.props.tagRanges = tagRanges;
|
|
64
|
+
tracked.props.event = new PropagationEvent({
|
|
65
|
+
context: new CallContext(data),
|
|
66
|
+
parents: [parentEvent],
|
|
67
|
+
signature,
|
|
68
|
+
source: 'P',
|
|
69
|
+
tagRanges,
|
|
70
|
+
target: 'R'
|
|
71
|
+
});
|
|
72
|
+
data.result = tracked.str;
|
|
73
|
+
}
|
|
73
74
|
}
|
|
74
75
|
});
|
|
75
76
|
}
|
|
@@ -42,7 +42,7 @@ module.exports.handle = function handle() {
|
|
|
42
42
|
if (!data.args[0] || !data.result) return;
|
|
43
43
|
|
|
44
44
|
const trackingData = tracker.getData(data.args[0]);
|
|
45
|
-
if (!trackingData
|
|
45
|
+
if (!trackingData) return;
|
|
46
46
|
|
|
47
47
|
// The path.extname() implementation does a substr on the argument
|
|
48
48
|
// based on the calculated index of the last dot
|
|
@@ -62,19 +62,20 @@ module.exports.handle = function handle() {
|
|
|
62
62
|
// no tags propagated to the result
|
|
63
63
|
if (!tagRanges.length) return;
|
|
64
64
|
|
|
65
|
-
const
|
|
66
|
-
const resultData = tracker.getData(result);
|
|
65
|
+
const tracked = tracker.track(data.result);
|
|
67
66
|
const parentEvent = trackingData.event;
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
67
|
+
if (tracked) {
|
|
68
|
+
tracked.props.tagRanges = tagRanges;
|
|
69
|
+
tracked.props.event = new PropagationEvent({
|
|
70
|
+
context: new CallContext(data),
|
|
71
|
+
parents: [parentEvent],
|
|
72
|
+
signature,
|
|
73
|
+
source: 'P',
|
|
74
|
+
tagRanges,
|
|
75
|
+
target: 'R'
|
|
76
|
+
});
|
|
77
|
+
data.result = tracked.str;
|
|
78
|
+
}
|
|
78
79
|
}
|
|
79
80
|
});
|
|
80
81
|
}
|
|
@@ -24,7 +24,7 @@ const propagate = function propagate(data) {
|
|
|
24
24
|
const props = tracker.getData(data.args[0]);
|
|
25
25
|
const { result } = data;
|
|
26
26
|
|
|
27
|
-
if (props
|
|
27
|
+
if (props && result) {
|
|
28
28
|
const membrane = new DeserializationMembrane(data, props);
|
|
29
29
|
data.result = membrane.wrap(result);
|
|
30
30
|
}
|
|
@@ -35,7 +35,7 @@ const provider = {
|
|
|
35
35
|
const { args, result } = data;
|
|
36
36
|
const trackData = tracker.getData(args[1]);
|
|
37
37
|
|
|
38
|
-
if (!trackData
|
|
38
|
+
if (!trackData) {
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -61,10 +61,12 @@ const provider = {
|
|
|
61
61
|
},
|
|
62
62
|
data
|
|
63
63
|
);
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
const tracked = tracker.track(data.result);
|
|
65
|
+
if (tracked) {
|
|
66
|
+
data.result = tracked.str;
|
|
67
|
+
tracked.props.tagRanges = shiftedRanges;
|
|
68
|
+
tracked.props.event = event;
|
|
69
|
+
}
|
|
68
70
|
}
|
|
69
71
|
},
|
|
70
72
|
/**
|
|
@@ -21,34 +21,36 @@ const qsUtils = require('./utils');
|
|
|
21
21
|
|
|
22
22
|
function handler(data) {
|
|
23
23
|
const input = data.args[0];
|
|
24
|
+
const trackedData = tracker.getData(input);
|
|
24
25
|
|
|
25
|
-
if (!input || !
|
|
26
|
+
if (!input || !trackedData) {
|
|
26
27
|
return;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
30
|
// adjust tag ranges
|
|
30
31
|
const tagRanges = [];
|
|
31
|
-
|
|
32
|
+
trackedData.tagRanges.forEach((tag) => {
|
|
32
33
|
tagRanges.push(qsUtils.adjustRangeEscape(tag, 0, input));
|
|
33
34
|
});
|
|
34
35
|
tagRanges.push(new TagRange(0, data.result.length - 1, 'url-encoded'));
|
|
35
36
|
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
37
|
+
const tracked = tracker.track(data.result);
|
|
38
|
+
if (tracked) {
|
|
39
|
+
tracked.props.tagRanges = tagRanges;
|
|
40
|
+
tracked.props.event = new PropagationEvent({
|
|
41
|
+
context: new CallContext({
|
|
42
|
+
...data,
|
|
43
|
+
obj: null
|
|
44
|
+
}),
|
|
45
|
+
parents: [tracked.props.event],
|
|
46
|
+
signature: new Signature('querystring.escape'),
|
|
47
|
+
source: 'P',
|
|
48
|
+
target: 'R',
|
|
49
|
+
tagRanges,
|
|
50
|
+
tags: ['url-encoded']
|
|
51
|
+
});
|
|
52
|
+
data.result = tracked.str;
|
|
53
|
+
}
|
|
52
54
|
}
|
|
53
55
|
|
|
54
56
|
module.exports.handle = handler;
|
|
@@ -47,9 +47,11 @@ function getUnescapeWrapper(data, unescape) {
|
|
|
47
47
|
|
|
48
48
|
// track the part w/ trimmed ranges if applicable
|
|
49
49
|
if (tagRanges.length) {
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
const tracked = tracker.track(part);
|
|
51
|
+
if (tracked) {
|
|
52
|
+
result = tracked.str;
|
|
53
|
+
tracked.props.tagRanges = tagRanges;
|
|
54
|
+
}
|
|
53
55
|
} else {
|
|
54
56
|
result = part;
|
|
55
57
|
}
|
|
@@ -58,7 +60,7 @@ function getUnescapeWrapper(data, unescape) {
|
|
|
58
60
|
result = Scopes.runInAllowAllScope(() => unescape(result));
|
|
59
61
|
resultData = tracker.getData(result);
|
|
60
62
|
|
|
61
|
-
if (resultData
|
|
63
|
+
if (resultData) {
|
|
62
64
|
resultData.event = new PropagationEvent({
|
|
63
65
|
context: new CallContext({
|
|
64
66
|
...data,
|
|
@@ -91,7 +93,7 @@ function pre(data) {
|
|
|
91
93
|
}
|
|
92
94
|
const trackingData = tracker.getData(input);
|
|
93
95
|
|
|
94
|
-
if (!trackingData
|
|
96
|
+
if (!trackingData) {
|
|
95
97
|
return;
|
|
96
98
|
}
|
|
97
99
|
|
|
@@ -129,7 +129,7 @@ class OnEscapeHandler {
|
|
|
129
129
|
// set current key for reference if when array-valued
|
|
130
130
|
this.currentKey = {
|
|
131
131
|
value: escaped,
|
|
132
|
-
tagRanges: trackingData
|
|
132
|
+
tagRanges: trackingData ? trackingData.tagRanges : null
|
|
133
133
|
};
|
|
134
134
|
|
|
135
135
|
// capture track info before updating state
|
|
@@ -175,7 +175,7 @@ class OnEscapeHandler {
|
|
|
175
175
|
this.offset += this.currentKey.value.length + this.eqLen;
|
|
176
176
|
}
|
|
177
177
|
|
|
178
|
-
if (trackingData
|
|
178
|
+
if (trackingData) {
|
|
179
179
|
ret.push({
|
|
180
180
|
offset: this.offset,
|
|
181
181
|
tagRanges: trackingData.tagRanges,
|
|
@@ -279,34 +279,35 @@ function post(data) {
|
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
const tracked = tracker.track(data.result);
|
|
282
|
-
const trackData = tracker.getData(tracked);
|
|
283
282
|
|
|
284
283
|
if (data.state.escape === querystring.escape) {
|
|
285
284
|
data.state.tagRanges.push(
|
|
286
285
|
new TagRange(0, data.result.length - 1, 'url-encoded')
|
|
287
286
|
);
|
|
288
287
|
}
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
288
|
+
if (tracked) {
|
|
289
|
+
const sorted = _.sortBy(data.state.tagRanges, 'start');
|
|
290
|
+
tracked.props.tagRanges = [];
|
|
291
|
+
tagRangeUtil.addAllInPlace(tracked.props.tagRanges, sorted);
|
|
292
|
+
|
|
293
|
+
// stringify / encode
|
|
294
|
+
const method = data.funcKey.split('.')[1];
|
|
295
|
+
|
|
296
|
+
tracked.props.event = new PropagationEvent({
|
|
297
|
+
context: new CallContext({
|
|
298
|
+
...data,
|
|
299
|
+
args: data.state.origArgs,
|
|
300
|
+
obj: null
|
|
301
|
+
}),
|
|
302
|
+
parents: Array.from(data.state.events),
|
|
303
|
+
signature: new Signature(`querystring.${method}`),
|
|
304
|
+
source: 'P',
|
|
305
|
+
tagRanges: tracked.props.tagRanges,
|
|
306
|
+
target: 'R',
|
|
307
|
+
tags: ['url-encoded']
|
|
308
|
+
});
|
|
309
|
+
data.result = tracked.str;
|
|
310
|
+
}
|
|
310
311
|
}
|
|
311
312
|
|
|
312
313
|
module.exports.handle = { pre, post };
|
|
@@ -20,14 +20,15 @@ const qsUtils = require('./utils');
|
|
|
20
20
|
|
|
21
21
|
function handler(data) {
|
|
22
22
|
const input = data.args[0];
|
|
23
|
+
const trackedData = tracker.getData(input);
|
|
23
24
|
|
|
24
|
-
if (!input || !
|
|
25
|
+
if (!input || !trackedData) {
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
// adjust tag ranges
|
|
29
30
|
const tagRanges = [];
|
|
30
|
-
|
|
31
|
+
trackedData.tagRanges.forEach((tag) => {
|
|
31
32
|
if (tag.tag === 'url-encoded') {
|
|
32
33
|
return;
|
|
33
34
|
}
|
|
@@ -37,22 +38,23 @@ function handler(data) {
|
|
|
37
38
|
return;
|
|
38
39
|
}
|
|
39
40
|
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
41
|
+
const tracked = tracker.track(data.result);
|
|
42
|
+
if (tracked) {
|
|
43
|
+
tracked.props.tagRanges = tagRanges;
|
|
44
|
+
tracked.props.event = new PropagationEvent({
|
|
45
|
+
context: new CallContext({
|
|
46
|
+
...data,
|
|
47
|
+
obj: null
|
|
48
|
+
}),
|
|
49
|
+
parents: [tracked.props.event],
|
|
50
|
+
signature: new Signature('querystring.unescape'),
|
|
51
|
+
source: 'P',
|
|
52
|
+
tagRanges,
|
|
53
|
+
target: 'R',
|
|
54
|
+
untags: ['url-encoded']
|
|
55
|
+
});
|
|
56
|
+
data.result = tracked.str;
|
|
57
|
+
}
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
module.exports.handle = handler;
|