@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
|
@@ -44,7 +44,7 @@ module.exports.handle = function() {
|
|
|
44
44
|
post(data) {
|
|
45
45
|
// else either the replacement value or a values in the array replacement is being tracked
|
|
46
46
|
const trackingData = tracker.getData(data.result);
|
|
47
|
-
if (!trackingData
|
|
47
|
+
if (!trackingData) {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
50
50
|
|
|
@@ -59,7 +59,7 @@ module.exports.handle = function() {
|
|
|
59
59
|
const len = positions.length; // micro optomized since used multiple times
|
|
60
60
|
|
|
61
61
|
for (let i = 0; i < len; i++) {
|
|
62
|
-
const
|
|
62
|
+
const props = tracker.getData(replacements[i]);
|
|
63
63
|
// we don't need to run in a no instrumentation scope here since
|
|
64
64
|
// patcher will do so automatically since we're in a post hook
|
|
65
65
|
const escapedVal = getSequelizeString().escape(
|
|
@@ -69,7 +69,7 @@ module.exports.handle = function() {
|
|
|
69
69
|
true // true is required to get format function behavior.
|
|
70
70
|
);
|
|
71
71
|
|
|
72
|
-
if (
|
|
72
|
+
if (props && props.tracked) {
|
|
73
73
|
tagRangeUtil.addInPlace(
|
|
74
74
|
trackingData.tagRanges,
|
|
75
75
|
new TagRange(
|
|
@@ -22,8 +22,8 @@ const tracker = require('../../../tracker');
|
|
|
22
22
|
*/
|
|
23
23
|
module.exports.isTracked = function isTracked(value) {
|
|
24
24
|
return Array.isArray(value)
|
|
25
|
-
? value.some((v) => typeof v === 'string' && tracker.getData(v)
|
|
26
|
-
: tracker.getData(value)
|
|
25
|
+
? value.some((v) => typeof v === 'string' && tracker.getData(v))
|
|
26
|
+
: !!tracker.getData(value);
|
|
27
27
|
};
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -115,13 +115,13 @@ function getTrackData(callContext) {
|
|
|
115
115
|
};
|
|
116
116
|
|
|
117
117
|
const objData = tracker.getData(callContext.obj);
|
|
118
|
-
if (objData
|
|
118
|
+
if (objData) {
|
|
119
119
|
trackData.objData = objData;
|
|
120
120
|
trackData.resultTagRanges = objData.tagRanges.map((r) => r.clone());
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
const replacerData = tracker.getData(callContext.args[1]);
|
|
124
|
-
if (replacerData
|
|
124
|
+
if (replacerData) {
|
|
125
125
|
trackData.replacerData = replacerData;
|
|
126
126
|
}
|
|
127
127
|
|
|
@@ -243,7 +243,7 @@ function getReplacementAndCaptureDynamicTags({ callContext, args }) {
|
|
|
243
243
|
// Allow propagation within replacer function so we can track return value.
|
|
244
244
|
_replacer = invokeReplacer({ callContext, args, replacer });
|
|
245
245
|
const data = tracker.getData(_replacer);
|
|
246
|
-
if (data
|
|
246
|
+
if (data) {
|
|
247
247
|
trackData.dynamicTagRanges = data.tagRanges;
|
|
248
248
|
trackData.dynamicEvents.add(data.event);
|
|
249
249
|
} else {
|
|
@@ -297,7 +297,7 @@ function wrapOriginalReplacerArguments({ callContext, args }) {
|
|
|
297
297
|
// Only wrap arguments that are used by replacer,
|
|
298
298
|
for (let idx = 0; idx < replacer.length; idx++) {
|
|
299
299
|
// and only track if needed
|
|
300
|
-
if (tracker.getData(args[idx])
|
|
300
|
+
if (tracker.getData(args[idx])) {
|
|
301
301
|
continue;
|
|
302
302
|
}
|
|
303
303
|
trackReplacerArgAtPath({
|
|
@@ -330,20 +330,21 @@ function trackReplacerArgAtPath({ callContext, target, path, tagRanges }) {
|
|
|
330
330
|
continue;
|
|
331
331
|
}
|
|
332
332
|
|
|
333
|
-
const
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
333
|
+
const tracked = tracker.track(_result);
|
|
334
|
+
if (tracked) {
|
|
335
|
+
// TODO: Improve accuracy here by deriving actual ranges from source,
|
|
336
|
+
// rather than applying "blanket" ranges the length of argument.
|
|
337
|
+
const tagRange = new TagRange(0, tracked.str.length - 1, tag);
|
|
338
|
+
tracked.props.tagRanges.push(tagRange);
|
|
339
|
+
tracked.props.event = createPropagationEvent({
|
|
340
|
+
callContext,
|
|
341
|
+
tagRanges: [tagRange],
|
|
342
|
+
result: tracked.str
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
captured.add(tag);
|
|
346
|
+
target[path] = tracked.str;
|
|
347
|
+
}
|
|
347
348
|
}
|
|
348
349
|
} else if (_.isObject(_result)) {
|
|
349
350
|
for (const path of Object.keys(_result)) {
|
|
@@ -582,20 +583,21 @@ function trackFinalResult(callContext) {
|
|
|
582
583
|
return;
|
|
583
584
|
}
|
|
584
585
|
|
|
585
|
-
if (tracker.getData(callContext.result)
|
|
586
|
+
if (tracker.getData(callContext.result)) {
|
|
586
587
|
return;
|
|
587
588
|
}
|
|
588
589
|
|
|
589
|
-
const
|
|
590
|
-
callContext.result = result;
|
|
590
|
+
const tracked = tracker.track(callContext.result);
|
|
591
591
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
592
|
+
if (tracked) {
|
|
593
|
+
tracked.props.event = createPropagationEvent({
|
|
594
|
+
callContext,
|
|
595
|
+
tagRanges: trackData.resultTagRanges,
|
|
596
|
+
result: tracked.str
|
|
597
|
+
});
|
|
598
|
+
tracked.props.tagRanges = trackData.resultTagRanges;
|
|
599
|
+
callContext.result = tracked.str;
|
|
600
|
+
}
|
|
599
601
|
}
|
|
600
602
|
|
|
601
603
|
/**
|
|
@@ -164,28 +164,27 @@ module.exports.handle = {
|
|
|
164
164
|
if (tagStart !== null) {
|
|
165
165
|
newTagRanges.push(new TagRange(tagStart, tagStop, tag.tag));
|
|
166
166
|
const tracked = tracker.track(stringPart);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
167
|
+
if (tracked) {
|
|
168
|
+
tracked.props.tagRanges.push(new TagRange(tagStart, tagStop, tag.tag));
|
|
169
|
+
result[i] = tracked.str;
|
|
170
170
|
}
|
|
171
|
-
props.tagRanges.push(new TagRange(tagStart, tagStop, tag.tag));
|
|
172
|
-
result[i] = tracked;
|
|
173
171
|
}
|
|
174
172
|
});
|
|
175
173
|
if (newTagRanges.length > 0) {
|
|
176
174
|
const tracked = tracker.track(stringPart);
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
175
|
+
if (tracked) {
|
|
176
|
+
tracked.props.tagRanges = newTagRanges;
|
|
177
|
+
result[i] = tracked.str;
|
|
178
|
+
const event = new PropagationEvent({
|
|
179
|
+
context: ctxt,
|
|
180
|
+
signature: sig,
|
|
181
|
+
tagRanges: tracked.props.tagRanges,
|
|
182
|
+
source: 'O',
|
|
183
|
+
target: 'R'
|
|
184
|
+
});
|
|
185
|
+
event.parents.push(oldEvent);
|
|
186
|
+
tracked.props.event = event;
|
|
187
|
+
}
|
|
189
188
|
}
|
|
190
189
|
}
|
|
191
190
|
data.result = result;
|
|
@@ -225,21 +224,21 @@ function handleEmptySeperator(data, oldTagRanges, oldEvent) {
|
|
|
225
224
|
if (sharedCharInfo.has(i)) {
|
|
226
225
|
info = sharedCharInfo.get(i);
|
|
227
226
|
} else {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
227
|
+
const tracked = tracker.track(char);
|
|
228
|
+
if (tracked) {
|
|
229
|
+
const event = new PropagationEvent({
|
|
230
|
+
context: ctxt,
|
|
231
|
+
signature: sig,
|
|
232
|
+
tagRanges: getTagRanges(tracked.str),
|
|
233
|
+
source: 'O',
|
|
234
|
+
target: 'R'
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
tracked.props.event = event;
|
|
238
|
+
info = { event, tagRanges: tracked.props.tagRanges };
|
|
239
|
+
sharedCharInfo.set(i, info);
|
|
240
|
+
result[i] = tracked.str;
|
|
241
|
+
}
|
|
243
242
|
}
|
|
244
243
|
|
|
245
244
|
info.tagRanges.push(new TagRange(0, 0, tag.tag));
|
|
@@ -257,10 +256,11 @@ function transferTracking(origString, resultArray) {
|
|
|
257
256
|
|
|
258
257
|
for (let i = 0; i < resultArray.length; i++) {
|
|
259
258
|
const tracked = tracker.track(resultArray[i]);
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
259
|
+
if (tracked) {
|
|
260
|
+
tracked.props.tagRanges = getTagRanges(origString);
|
|
261
|
+
tracked.props.event = getEvent(origString);
|
|
262
|
+
resultArray[i] = tracked.str;
|
|
263
|
+
}
|
|
264
264
|
}
|
|
265
265
|
return resultArray;
|
|
266
266
|
}
|
|
@@ -25,7 +25,7 @@ const signature = new Signature('String.prototype.trim');
|
|
|
25
25
|
function handle(data) {
|
|
26
26
|
const { obj, result } = data;
|
|
27
27
|
const sourceMetadata = tracker.getData(obj);
|
|
28
|
-
if (!sourceMetadata
|
|
28
|
+
if (!sourceMetadata) {
|
|
29
29
|
return;
|
|
30
30
|
}
|
|
31
31
|
|
|
@@ -43,21 +43,19 @@ function handle(data) {
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
const tracked = tracker.track(result);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
if (tracked) {
|
|
47
|
+
tracked.props.tagRanges = targetRanges;
|
|
48
|
+
const context = new CallContext(data);
|
|
49
|
+
const event = new PropagationEvent({
|
|
50
|
+
context,
|
|
51
|
+
signature,
|
|
52
|
+
tagRanges: targetRanges,
|
|
53
|
+
source: 'O',
|
|
54
|
+
target: 'R'
|
|
55
|
+
});
|
|
56
|
+
event.parents.push(sourceEvent);
|
|
57
|
+
tracked.props.event = event;
|
|
58
|
+
|
|
59
|
+
data.result = tracked.str;
|
|
49
60
|
}
|
|
50
|
-
trackedData.tagRanges = targetRanges;
|
|
51
|
-
const context = new CallContext(data);
|
|
52
|
-
const event = new PropagationEvent({
|
|
53
|
-
context,
|
|
54
|
-
signature,
|
|
55
|
-
tagRanges: targetRanges,
|
|
56
|
-
source: 'O',
|
|
57
|
-
target: 'R'
|
|
58
|
-
});
|
|
59
|
-
event.parents.push(sourceEvent);
|
|
60
|
-
trackedData.event = event;
|
|
61
|
-
|
|
62
|
-
data.result = tracked;
|
|
63
61
|
}
|
|
@@ -41,30 +41,26 @@ function handle() {
|
|
|
41
41
|
|
|
42
42
|
// Checks if the string literal form of the new String object is tracked.
|
|
43
43
|
// If so, we will want to copy the existing tag ranges below.
|
|
44
|
-
if (data.obj && !argData
|
|
44
|
+
if (data.obj && !argData) {
|
|
45
45
|
argData = tracker.getData(data.result.toString());
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
if (!arg || !argData
|
|
48
|
+
if (!arg || !argData) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
const
|
|
53
|
-
|
|
52
|
+
const tracked = tracker.track(data.result);
|
|
53
|
+
if (tracked) {
|
|
54
|
+
// In a constructor context, data.obj is set to the new String object.
|
|
55
|
+
// When a new String object is instantiated we must copy the existing tag
|
|
56
|
+
// ranges from the string literal to the new String object.
|
|
57
|
+
if (data.obj) {
|
|
58
|
+
tracked.props.event = argData.event;
|
|
59
|
+
tracked.props.tagRanges = tracked.props.tagRanges.concat(argData.tagRanges);
|
|
60
|
+
}
|
|
54
61
|
|
|
55
|
-
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// In a constructor context, data.obj is set to the new String object.
|
|
60
|
-
// When a new String object is instantiated we must copy the existing tag
|
|
61
|
-
// ranges from the string literal to the new String object.
|
|
62
|
-
if (data.obj) {
|
|
63
|
-
newStrData.event = argData.event;
|
|
64
|
-
newStrData.tagRanges = newStrData.tagRanges.concat(argData.tagRanges);
|
|
62
|
+
data.result = tracked.str;
|
|
65
63
|
}
|
|
66
|
-
|
|
67
|
-
data.result = newStr;
|
|
68
64
|
}
|
|
69
65
|
});
|
|
70
66
|
}
|
|
@@ -50,35 +50,38 @@ function getEscapedTagRanges(input, result, start, stop, tag) {
|
|
|
50
50
|
function propagator(data, tagName, signatureName) {
|
|
51
51
|
const input = data.args[0];
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
const trackedData = tracker.getData(input);
|
|
54
|
+
|
|
55
|
+
if (!input || !trackedData) {
|
|
54
56
|
return;
|
|
55
57
|
}
|
|
56
58
|
|
|
57
59
|
// adjust tag ranges
|
|
58
60
|
const tagRanges = [];
|
|
59
|
-
|
|
61
|
+
trackedData.tagRanges.forEach((range) => {
|
|
60
62
|
const { start, stop, tag } = range;
|
|
61
63
|
tagRanges.push(
|
|
62
64
|
...getEscapedTagRanges(input, data.result, start, stop, tag)
|
|
63
65
|
);
|
|
64
66
|
});
|
|
65
67
|
tagRanges.push(new TagRange(0, data.result.length - 1, tagName));
|
|
66
|
-
const
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
68
|
+
const tracked = tracker.track(data.result);
|
|
69
|
+
if (tracked) {
|
|
70
|
+
tracked.props.tagRanges = tagRanges;
|
|
71
|
+
tracked.props.event = new PropagationEvent({
|
|
72
|
+
context: new CallContext({
|
|
73
|
+
...data,
|
|
74
|
+
obj: null
|
|
75
|
+
}),
|
|
76
|
+
parents: [tracked.props.event],
|
|
77
|
+
signature: new Signature(signatureName),
|
|
78
|
+
source: 'P',
|
|
79
|
+
target: 'R',
|
|
80
|
+
tagRanges,
|
|
81
|
+
tags: tagName
|
|
82
|
+
});
|
|
83
|
+
data.result = tracked.str;
|
|
84
|
+
}
|
|
82
85
|
}
|
|
83
86
|
|
|
84
87
|
module.exports.propagate = propagator;
|
|
@@ -75,17 +75,17 @@ function __contrastTag(...args) {
|
|
|
75
75
|
});
|
|
76
76
|
|
|
77
77
|
if (tagRanges.length > 0) {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
if (resultContrastProperties.tracked) {
|
|
78
|
+
const tracked = tracker.track(result);
|
|
79
|
+
if (tracked) {
|
|
81
80
|
buildProperties(
|
|
82
|
-
|
|
81
|
+
tracked.props,
|
|
83
82
|
tagRanges,
|
|
84
83
|
expressions,
|
|
85
|
-
|
|
84
|
+
tracked.str,
|
|
86
85
|
strings,
|
|
87
86
|
sourceEvents
|
|
88
87
|
);
|
|
88
|
+
result = tracked.str;
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
|
|
@@ -143,18 +143,18 @@ function buildProperties(props, tagRanges, exps, result, strings, events) {
|
|
|
143
143
|
*/
|
|
144
144
|
function moveTags(exp, sourceEvents, tagRanges, offset) {
|
|
145
145
|
const contrastProperties = tracker.getData(exp);
|
|
146
|
-
const tracked = contrastProperties
|
|
146
|
+
const tracked = contrastProperties || tagRanges.length > 0;
|
|
147
147
|
if (!tracked) {
|
|
148
148
|
return tagRanges;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
-
const event = contrastProperties
|
|
151
|
+
const event = contrastProperties && contrastProperties.event;
|
|
152
152
|
if (event) {
|
|
153
153
|
sourceEvents.push(event);
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
let newTagRanges = [];
|
|
157
|
-
if (contrastProperties
|
|
157
|
+
if (contrastProperties) newTagRanges = contrastProperties.tagRanges;
|
|
158
158
|
|
|
159
159
|
return tagRangeUtil.addAllWithOffset(tagRanges, newTagRanges, offset);
|
|
160
160
|
}
|
|
@@ -45,7 +45,7 @@ function handle(data) {
|
|
|
45
45
|
const address = data.args[0];
|
|
46
46
|
const sourceMetadata = tracker.getData(address);
|
|
47
47
|
|
|
48
|
-
if (!sourceMetadata
|
|
48
|
+
if (!sourceMetadata) {
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -71,9 +71,8 @@ function propagate(sourceMetadata, address, data) {
|
|
|
71
71
|
|
|
72
72
|
if (part && typeof part === 'string' && part !== '') {
|
|
73
73
|
const tracked = tracker.track(part);
|
|
74
|
-
const trackedData = tracker.getData(tracked);
|
|
75
74
|
|
|
76
|
-
if (!
|
|
75
|
+
if (!tracked) {
|
|
77
76
|
continue;
|
|
78
77
|
}
|
|
79
78
|
|
|
@@ -105,10 +104,10 @@ function propagate(sourceMetadata, address, data) {
|
|
|
105
104
|
);
|
|
106
105
|
event.parents.push(sourceEvent);
|
|
107
106
|
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
tracked.props.tagRanges = targetTagRanges;
|
|
108
|
+
tracked.props.event = event;
|
|
110
109
|
|
|
111
|
-
url[key] = tracked;
|
|
110
|
+
url[key] = tracked.str;
|
|
112
111
|
}
|
|
113
112
|
}
|
|
114
113
|
}
|
|
@@ -71,6 +71,9 @@ function setHostnamePortTags(urlObj, stack, args, sourceEvent) {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
const hostData = tracker.getData(urlObj._contrast_host);
|
|
74
|
+
if (!hostData) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
74
77
|
const hostnameTags = tagRangeUtil.trim(hostData.tagRanges, 0, splitIndex - 1);
|
|
75
78
|
const portTags = tagRangeUtil.trim(
|
|
76
79
|
hostData.tagRanges,
|
|
@@ -81,21 +84,25 @@ function setHostnamePortTags(urlObj, stack, args, sourceEvent) {
|
|
|
81
84
|
|
|
82
85
|
if (hostnameTags.length > 0) {
|
|
83
86
|
const hostnameTracked = tracker.track(hostname);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
87
|
+
if (hostnameTracked) {
|
|
88
|
+
hostnameTracked.props.tagRanges = hostnameTags;
|
|
89
|
+
urlObj._contrast_hostname = hostnameTracked.str;
|
|
90
|
+
event = createEvent('url.URL', stack, hostnameTags, hostname, args, urlObj);
|
|
91
|
+
event.parents.push(sourceEvent);
|
|
92
|
+
event.tagRanges = hostnameTags;
|
|
93
|
+
hostnameTracked.props.event = event;
|
|
94
|
+
}
|
|
90
95
|
}
|
|
91
96
|
if (portTags.length > 0) {
|
|
92
97
|
const portTracked = tracker.track(port);
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
98
|
+
if (portTracked) {
|
|
99
|
+
portTracked.props.tagRanges = portTags;
|
|
100
|
+
urlObj._contrast_port = portTracked.str;
|
|
101
|
+
event = createEvent('url.URL', stack, portTags, port, args, urlObj);
|
|
102
|
+
event.parents.push(sourceEvent);
|
|
103
|
+
event.tagRanges = portTags;
|
|
104
|
+
portTracked.props.event = event;
|
|
105
|
+
}
|
|
99
106
|
}
|
|
100
107
|
}
|
|
101
108
|
|
|
@@ -136,26 +143,28 @@ function joinProperties(urlObj, sourceProps, separators) {
|
|
|
136
143
|
}
|
|
137
144
|
|
|
138
145
|
// copy tag ranges
|
|
139
|
-
const result = tracker.track(value);
|
|
140
146
|
let valIdx = 0;
|
|
141
147
|
sepIdx = 0;
|
|
142
148
|
let tags = [];
|
|
143
149
|
|
|
144
150
|
for (const prop of sourceProps) {
|
|
145
|
-
|
|
151
|
+
const trackedPropData = tracker.getData(urlObj[`_contrast_${prop}`]);
|
|
152
|
+
if (trackedPropData) {
|
|
146
153
|
tags = tagRangeUtil.addAll(
|
|
147
154
|
tags,
|
|
148
155
|
offsetTagRanges(
|
|
149
|
-
|
|
156
|
+
trackedPropData.tagRanges,
|
|
150
157
|
valIdx
|
|
151
158
|
)
|
|
152
159
|
);
|
|
153
160
|
}
|
|
154
161
|
valIdx += urlObj[prop].length + separators[sepIdx++].length;
|
|
155
162
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
163
|
+
const tracked = tracker.track(value);
|
|
164
|
+
if (tracked) {
|
|
165
|
+
tracked.props.tagRanges = tags;
|
|
166
|
+
return tracked.str;
|
|
167
|
+
}
|
|
159
168
|
}
|
|
160
169
|
|
|
161
170
|
/**
|
|
@@ -172,7 +181,8 @@ function setOriginTags(urlObj, stack, args, sourceEvent) {
|
|
|
172
181
|
//
|
|
173
182
|
|
|
174
183
|
const trackedOrigin = joinProperties(urlObj, SET_ORIGIN_TAGS, ['//', '']);
|
|
175
|
-
|
|
184
|
+
const trackedOriginData = tracker.getData(trackedOrigin);
|
|
185
|
+
if (!trackedOriginData || trackedOriginData.tagRanges.length === 0) {
|
|
176
186
|
return;
|
|
177
187
|
}
|
|
178
188
|
urlObj._contrast_origin = trackedOrigin;
|
|
@@ -180,14 +190,14 @@ function setOriginTags(urlObj, stack, args, sourceEvent) {
|
|
|
180
190
|
const event = createEvent(
|
|
181
191
|
'url.URL',
|
|
182
192
|
stack,
|
|
183
|
-
|
|
193
|
+
trackedOriginData.tagRanges,
|
|
184
194
|
trackedOrigin,
|
|
185
195
|
args,
|
|
186
196
|
urlObj
|
|
187
197
|
);
|
|
188
198
|
event.parents.push(sourceEvent);
|
|
189
|
-
event.tagRanges =
|
|
190
|
-
|
|
199
|
+
event.tagRanges = trackedOriginData.tagRanges;
|
|
200
|
+
trackedOriginData.event = event;
|
|
191
201
|
}
|
|
192
202
|
|
|
193
203
|
/**
|
|
@@ -221,7 +231,7 @@ function setHrefTags(urlObj, stack, args, sourceEvent) {
|
|
|
221
231
|
|
|
222
232
|
const joinedHref = joinProperties(urlObj, properties, separators);
|
|
223
233
|
const joinedHrefData = tracker.getData(joinedHref);
|
|
224
|
-
if (joinedHrefData.tagRanges.length === 0) {
|
|
234
|
+
if (!joinedHrefData || joinedHrefData.tagRanges.length === 0) {
|
|
225
235
|
return;
|
|
226
236
|
}
|
|
227
237
|
urlObj._contrast_href = joinedHref;
|
|
@@ -235,7 +245,7 @@ function setHrefTags(urlObj, stack, args, sourceEvent) {
|
|
|
235
245
|
);
|
|
236
246
|
event.parents.push(sourceEvent);
|
|
237
247
|
event.tagRanges = joinedHrefData.tagRanges;
|
|
238
|
-
|
|
248
|
+
joinedHrefData.event = event;
|
|
239
249
|
}
|
|
240
250
|
|
|
241
251
|
/**
|
|
@@ -300,21 +310,22 @@ function copyTagsSingleSource(sourceTagRanges, sourceEvent, data) {
|
|
|
300
310
|
copied = true;
|
|
301
311
|
const trackedKey = `_contrast_${key}`;
|
|
302
312
|
const tracked = tracker.track(val);
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
313
|
+
if (tracked) {
|
|
314
|
+
tracked.props.tagRanges = trimmed;
|
|
315
|
+
urlObj[trackedKey] = tracked.str;
|
|
316
|
+
|
|
317
|
+
// only create the stack once because stack creation is expensive
|
|
318
|
+
stack =
|
|
319
|
+
stack ||
|
|
320
|
+
stackFactory.createSnapshot({
|
|
321
|
+
constructorOpt: data.hooked
|
|
322
|
+
})();
|
|
323
|
+
|
|
324
|
+
event = createEvent('url.URL', stack, trimmed, val, args, urlObj);
|
|
325
|
+
event.parents.push(sourceEvent);
|
|
326
|
+
event.tagRanges = trimmed;
|
|
327
|
+
tracked.props.event = event;
|
|
328
|
+
}
|
|
318
329
|
}
|
|
319
330
|
|
|
320
331
|
if (!copied) {
|
|
@@ -351,10 +362,7 @@ function callUnwrapped(input) {
|
|
|
351
362
|
*/
|
|
352
363
|
function skipTracking(inputData, baseData) {
|
|
353
364
|
// if neither input or base are tracked we can just skip tracking
|
|
354
|
-
if (
|
|
355
|
-
(!inputData.tracked && baseData && !baseData.tracked) ||
|
|
356
|
-
(!inputData.tracked && !baseData)
|
|
357
|
-
) {
|
|
365
|
+
if (!inputData && !baseData) {
|
|
358
366
|
return true;
|
|
359
367
|
}
|
|
360
368
|
return false;
|
|
@@ -266,7 +266,7 @@ const propagate = function propagate(util, data) {
|
|
|
266
266
|
};
|
|
267
267
|
|
|
268
268
|
const fmtStrMeta = tracker.getData(fmtStr);
|
|
269
|
-
if (fmtStrMeta
|
|
269
|
+
if (fmtStrMeta) {
|
|
270
270
|
resultMeta.fmtStrTagRanges = fmtStrMeta.tagRanges.map((tagRange) =>
|
|
271
271
|
tagRangeWithOriginals(
|
|
272
272
|
new TagRange(tagRange.start, tagRange.stop, tagRange.tag)
|