@newrelic/browser-agent 1.278.2 → 1.278.3
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/CHANGELOG.md +7 -0
- package/dist/cjs/common/constants/env.cdn.js +1 -1
- package/dist/cjs/common/constants/env.npm.js +1 -1
- package/dist/cjs/common/util/obfuscate.js +26 -48
- package/dist/cjs/features/metrics/aggregate/index.js +1 -3
- package/dist/cjs/features/utils/aggregate-base.js +1 -1
- package/dist/esm/common/constants/env.cdn.js +1 -1
- package/dist/esm/common/constants/env.npm.js +1 -1
- package/dist/esm/common/util/obfuscate.js +26 -48
- package/dist/esm/features/metrics/aggregate/index.js +1 -3
- package/dist/esm/features/utils/aggregate-base.js +1 -1
- package/dist/types/common/util/obfuscate.d.ts +11 -20
- package/dist/types/common/util/obfuscate.d.ts.map +1 -1
- package/dist/types/features/metrics/aggregate/index.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/common/util/obfuscate.js +27 -47
- package/src/features/metrics/aggregate/index.js +1 -3
- package/src/features/utils/aggregate-base.js +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [1.278.3](https://github.com/newrelic/newrelic-browser-agent/compare/v1.278.2...v1.278.3) (2025-01-14)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* Change obfuscator to read directly from obfuscation rules configuration ([#1327](https://github.com/newrelic/newrelic-browser-agent/issues/1327)) ([a75f935](https://github.com/newrelic/newrelic-browser-agent/commit/a75f935d9b045ac74878f7dd1fab04d046b376dc))
|
|
12
|
+
|
|
6
13
|
## [1.278.2](https://github.com/newrelic/newrelic-browser-agent/compare/v1.278.1...v1.278.2) (2025-01-09)
|
|
7
14
|
|
|
8
15
|
|
|
@@ -12,7 +12,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
|
|
|
12
12
|
/**
|
|
13
13
|
* Exposes the version of the agent
|
|
14
14
|
*/
|
|
15
|
-
const VERSION = exports.VERSION = "1.278.
|
|
15
|
+
const VERSION = exports.VERSION = "1.278.3";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the build type of the agent
|
|
@@ -12,7 +12,7 @@ exports.VERSION = exports.RRWEB_VERSION = exports.DIST_METHOD = exports.BUILD_EN
|
|
|
12
12
|
/**
|
|
13
13
|
* Exposes the version of the agent
|
|
14
14
|
*/
|
|
15
|
-
const VERSION = exports.VERSION = "1.278.
|
|
15
|
+
const VERSION = exports.VERSION = "1.278.3";
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* Exposes the build type of the agent
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.Obfuscator = void 0;
|
|
7
|
-
var _init = require("../config/init");
|
|
8
7
|
var _protocol = require("../url/protocol");
|
|
9
8
|
var _console = require("./console");
|
|
10
9
|
/**
|
|
@@ -26,16 +25,14 @@ var _console = require("./console");
|
|
|
26
25
|
*/
|
|
27
26
|
|
|
28
27
|
class Obfuscator {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
this.#ruleValidationCache = Obfuscator.getRuleValidationCache(agentIdentifier);
|
|
35
|
-
Obfuscator.logObfuscationRuleErrors(this.#ruleValidationCache);
|
|
28
|
+
constructor(agentRef) {
|
|
29
|
+
this.agentRef = agentRef;
|
|
30
|
+
this.warnedRegexMissing = false;
|
|
31
|
+
this.warnedInvalidRegex = false;
|
|
32
|
+
this.warnedInvalidReplacement = false;
|
|
36
33
|
}
|
|
37
|
-
get
|
|
38
|
-
return this
|
|
34
|
+
get obfuscateConfigRules() {
|
|
35
|
+
return this.agentRef.init.obfuscate || [];
|
|
39
36
|
}
|
|
40
37
|
|
|
41
38
|
/**
|
|
@@ -46,31 +43,19 @@ class Obfuscator {
|
|
|
46
43
|
obfuscateString(input) {
|
|
47
44
|
// if input is not of type string or is an empty string, short-circuit
|
|
48
45
|
if (typeof input !== 'string' || input.trim().length === 0) return input;
|
|
49
|
-
|
|
50
|
-
const {
|
|
51
|
-
rule
|
|
52
|
-
} = ruleValidation;
|
|
53
|
-
return input.replace(rule.regex, rule.replacement || '*');
|
|
54
|
-
}, input);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Returns an array of obfuscation rules to be applied to harvested payloads
|
|
59
|
-
* @param {string} agentIdentifier The agent identifier to get rules for
|
|
60
|
-
* @returns {ObfuscationRuleValidation[]} The array of rules or validation states
|
|
61
|
-
*/
|
|
62
|
-
static getRuleValidationCache(agentIdentifier) {
|
|
63
|
-
/**
|
|
64
|
-
* @type {ObfuscationRule[]}
|
|
65
|
-
*/
|
|
66
|
-
let rules = (0, _init.getConfigurationValue)(agentIdentifier, 'obfuscate') || [];
|
|
46
|
+
const rules = this.obfuscateConfigRules.map(rule => this.validateObfuscationRule(rule));
|
|
67
47
|
if ((0, _protocol.isFileProtocol)()) {
|
|
68
48
|
rules.push({
|
|
69
49
|
regex: /^file:\/\/(.*)/,
|
|
70
50
|
replacement: atob('ZmlsZTovL09CRlVTQ0FURUQ=')
|
|
71
51
|
});
|
|
72
52
|
}
|
|
73
|
-
return rules.
|
|
53
|
+
return rules.filter(ruleValidation => ruleValidation.isValid).reduce((input, ruleValidation) => {
|
|
54
|
+
const {
|
|
55
|
+
rule
|
|
56
|
+
} = ruleValidation;
|
|
57
|
+
return input.replace(rule.regex, rule.replacement || '*');
|
|
58
|
+
}, input);
|
|
74
59
|
}
|
|
75
60
|
|
|
76
61
|
/**
|
|
@@ -78,10 +63,21 @@ class Obfuscator {
|
|
|
78
63
|
* @param {ObfuscationRule} rule The rule to validate
|
|
79
64
|
* @returns {ObfuscationRuleValidation} The validation state of the rule
|
|
80
65
|
*/
|
|
81
|
-
|
|
66
|
+
validateObfuscationRule(rule) {
|
|
82
67
|
const regexMissingDetected = Boolean(rule.regex === undefined);
|
|
83
68
|
const invalidRegexDetected = Boolean(rule.regex !== undefined && typeof rule.regex !== 'string' && !(rule.regex instanceof RegExp));
|
|
84
69
|
const invalidReplacementDetected = Boolean(rule.replacement && typeof rule.replacement !== 'string');
|
|
70
|
+
if (regexMissingDetected && !this.warnedRegexMissing) {
|
|
71
|
+
(0, _console.warn)(12, rule);
|
|
72
|
+
this.warnedRegexMissing = true;
|
|
73
|
+
} else if (invalidRegexDetected && !this.warnedInvalidRegex) {
|
|
74
|
+
(0, _console.warn)(13, rule);
|
|
75
|
+
this.warnedInvalidRegex = true;
|
|
76
|
+
}
|
|
77
|
+
if (invalidReplacementDetected && !this.warnedInvalidReplacement) {
|
|
78
|
+
(0, _console.warn)(14, rule);
|
|
79
|
+
this.warnedInvalidReplacement = true;
|
|
80
|
+
}
|
|
85
81
|
return {
|
|
86
82
|
rule,
|
|
87
83
|
isValid: !regexMissingDetected && !invalidRegexDetected && !invalidReplacementDetected,
|
|
@@ -92,23 +88,5 @@ class Obfuscator {
|
|
|
92
88
|
}
|
|
93
89
|
};
|
|
94
90
|
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Logs any obfuscation rule errors to the console. This is called when an obfuscator
|
|
98
|
-
* instance is created.
|
|
99
|
-
* @param {ObfuscationRuleValidation[]} ruleValidationCache The cache of rule validation states
|
|
100
|
-
*/
|
|
101
|
-
static logObfuscationRuleErrors(ruleValidationCache) {
|
|
102
|
-
for (const ruleValidation of ruleValidationCache) {
|
|
103
|
-
const {
|
|
104
|
-
rule,
|
|
105
|
-
isValid,
|
|
106
|
-
errors
|
|
107
|
-
} = ruleValidation;
|
|
108
|
-
if (isValid) continue;
|
|
109
|
-
if (errors.regexMissingDetected) (0, _console.warn)(12, rule);else if (errors.invalidRegexDetected) (0, _console.warn)(13, rule);
|
|
110
|
-
if (errors.invalidReplacementDetected) (0, _console.warn)(14, rule);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
91
|
}
|
|
114
92
|
exports.Obfuscator = Obfuscator;
|
|
@@ -97,10 +97,8 @@ class Aggregate extends _aggregateBase.AggregateBase {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// Capture SMs to assess customer engagement with the obfuscation config
|
|
100
|
-
|
|
101
|
-
if (ruleValidations.length > 0) {
|
|
100
|
+
if (this.obfuscator.obfuscateConfigRules.length > 0) {
|
|
102
101
|
this.storeSupportabilityMetrics('Generic/Obfuscate/Detected');
|
|
103
|
-
if (ruleValidations.filter(ruleValidation => !ruleValidation.isValid).length > 0) this.storeSupportabilityMetrics('Generic/Obfuscate/Invalid');
|
|
104
102
|
}
|
|
105
103
|
|
|
106
104
|
// Check if proxy for either chunks or beacon is being used
|
|
@@ -153,7 +153,7 @@ class AggregateBase extends _featureBase.FeatureBase {
|
|
|
153
153
|
* This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
|
|
154
154
|
*/
|
|
155
155
|
doOnceForAllAggregate(agentRef) {
|
|
156
|
-
if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new _obfuscate.Obfuscator(
|
|
156
|
+
if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new _obfuscate.Obfuscator(agentRef);
|
|
157
157
|
this.obfuscator = agentRef.runtime.obfuscator;
|
|
158
158
|
if (!agentRef.mainAppKey) agentRef.mainAppKey = {
|
|
159
159
|
licenseKey: agentRef.info.licenseKey,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getConfigurationValue } from '../config/init';
|
|
2
1
|
import { isFileProtocol } from '../url/protocol';
|
|
3
2
|
import { warn } from './console';
|
|
4
3
|
|
|
@@ -21,16 +20,14 @@ import { warn } from './console';
|
|
|
21
20
|
*/
|
|
22
21
|
|
|
23
22
|
export class Obfuscator {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.#ruleValidationCache = Obfuscator.getRuleValidationCache(agentIdentifier);
|
|
30
|
-
Obfuscator.logObfuscationRuleErrors(this.#ruleValidationCache);
|
|
23
|
+
constructor(agentRef) {
|
|
24
|
+
this.agentRef = agentRef;
|
|
25
|
+
this.warnedRegexMissing = false;
|
|
26
|
+
this.warnedInvalidRegex = false;
|
|
27
|
+
this.warnedInvalidReplacement = false;
|
|
31
28
|
}
|
|
32
|
-
get
|
|
33
|
-
return this
|
|
29
|
+
get obfuscateConfigRules() {
|
|
30
|
+
return this.agentRef.init.obfuscate || [];
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
/**
|
|
@@ -41,31 +38,19 @@ export class Obfuscator {
|
|
|
41
38
|
obfuscateString(input) {
|
|
42
39
|
// if input is not of type string or is an empty string, short-circuit
|
|
43
40
|
if (typeof input !== 'string' || input.trim().length === 0) return input;
|
|
44
|
-
|
|
45
|
-
const {
|
|
46
|
-
rule
|
|
47
|
-
} = ruleValidation;
|
|
48
|
-
return input.replace(rule.regex, rule.replacement || '*');
|
|
49
|
-
}, input);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Returns an array of obfuscation rules to be applied to harvested payloads
|
|
54
|
-
* @param {string} agentIdentifier The agent identifier to get rules for
|
|
55
|
-
* @returns {ObfuscationRuleValidation[]} The array of rules or validation states
|
|
56
|
-
*/
|
|
57
|
-
static getRuleValidationCache(agentIdentifier) {
|
|
58
|
-
/**
|
|
59
|
-
* @type {ObfuscationRule[]}
|
|
60
|
-
*/
|
|
61
|
-
let rules = getConfigurationValue(agentIdentifier, 'obfuscate') || [];
|
|
41
|
+
const rules = this.obfuscateConfigRules.map(rule => this.validateObfuscationRule(rule));
|
|
62
42
|
if (isFileProtocol()) {
|
|
63
43
|
rules.push({
|
|
64
44
|
regex: /^file:\/\/(.*)/,
|
|
65
45
|
replacement: atob('ZmlsZTovL09CRlVTQ0FURUQ=')
|
|
66
46
|
});
|
|
67
47
|
}
|
|
68
|
-
return rules.
|
|
48
|
+
return rules.filter(ruleValidation => ruleValidation.isValid).reduce((input, ruleValidation) => {
|
|
49
|
+
const {
|
|
50
|
+
rule
|
|
51
|
+
} = ruleValidation;
|
|
52
|
+
return input.replace(rule.regex, rule.replacement || '*');
|
|
53
|
+
}, input);
|
|
69
54
|
}
|
|
70
55
|
|
|
71
56
|
/**
|
|
@@ -73,10 +58,21 @@ export class Obfuscator {
|
|
|
73
58
|
* @param {ObfuscationRule} rule The rule to validate
|
|
74
59
|
* @returns {ObfuscationRuleValidation} The validation state of the rule
|
|
75
60
|
*/
|
|
76
|
-
|
|
61
|
+
validateObfuscationRule(rule) {
|
|
77
62
|
const regexMissingDetected = Boolean(rule.regex === undefined);
|
|
78
63
|
const invalidRegexDetected = Boolean(rule.regex !== undefined && typeof rule.regex !== 'string' && !(rule.regex instanceof RegExp));
|
|
79
64
|
const invalidReplacementDetected = Boolean(rule.replacement && typeof rule.replacement !== 'string');
|
|
65
|
+
if (regexMissingDetected && !this.warnedRegexMissing) {
|
|
66
|
+
warn(12, rule);
|
|
67
|
+
this.warnedRegexMissing = true;
|
|
68
|
+
} else if (invalidRegexDetected && !this.warnedInvalidRegex) {
|
|
69
|
+
warn(13, rule);
|
|
70
|
+
this.warnedInvalidRegex = true;
|
|
71
|
+
}
|
|
72
|
+
if (invalidReplacementDetected && !this.warnedInvalidReplacement) {
|
|
73
|
+
warn(14, rule);
|
|
74
|
+
this.warnedInvalidReplacement = true;
|
|
75
|
+
}
|
|
80
76
|
return {
|
|
81
77
|
rule,
|
|
82
78
|
isValid: !regexMissingDetected && !invalidRegexDetected && !invalidReplacementDetected,
|
|
@@ -87,22 +83,4 @@ export class Obfuscator {
|
|
|
87
83
|
}
|
|
88
84
|
};
|
|
89
85
|
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Logs any obfuscation rule errors to the console. This is called when an obfuscator
|
|
93
|
-
* instance is created.
|
|
94
|
-
* @param {ObfuscationRuleValidation[]} ruleValidationCache The cache of rule validation states
|
|
95
|
-
*/
|
|
96
|
-
static logObfuscationRuleErrors(ruleValidationCache) {
|
|
97
|
-
for (const ruleValidation of ruleValidationCache) {
|
|
98
|
-
const {
|
|
99
|
-
rule,
|
|
100
|
-
isValid,
|
|
101
|
-
errors
|
|
102
|
-
} = ruleValidation;
|
|
103
|
-
if (isValid) continue;
|
|
104
|
-
if (errors.regexMissingDetected) warn(12, rule);else if (errors.invalidRegexDetected) warn(13, rule);
|
|
105
|
-
if (errors.invalidReplacementDetected) warn(14, rule);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
86
|
}
|
|
@@ -91,10 +91,8 @@ export class Aggregate extends AggregateBase {
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
// Capture SMs to assess customer engagement with the obfuscation config
|
|
94
|
-
|
|
95
|
-
if (ruleValidations.length > 0) {
|
|
94
|
+
if (this.obfuscator.obfuscateConfigRules.length > 0) {
|
|
96
95
|
this.storeSupportabilityMetrics('Generic/Obfuscate/Detected');
|
|
97
|
-
if (ruleValidations.filter(ruleValidation => !ruleValidation.isValid).length > 0) this.storeSupportabilityMetrics('Generic/Obfuscate/Invalid');
|
|
98
96
|
}
|
|
99
97
|
|
|
100
98
|
// Check if proxy for either chunks or beacon is being used
|
|
@@ -147,7 +147,7 @@ export class AggregateBase extends FeatureBase {
|
|
|
147
147
|
* This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
|
|
148
148
|
*/
|
|
149
149
|
doOnceForAllAggregate(agentRef) {
|
|
150
|
-
if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new Obfuscator(
|
|
150
|
+
if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new Obfuscator(agentRef);
|
|
151
151
|
this.obfuscator = agentRef.runtime.obfuscator;
|
|
152
152
|
if (!agentRef.mainAppKey) agentRef.mainAppKey = {
|
|
153
153
|
licenseKey: agentRef.info.licenseKey,
|
|
@@ -15,33 +15,24 @@
|
|
|
15
15
|
* @property {boolean} errors.invalidReplacementDetected Whether the replacement is invalid
|
|
16
16
|
*/
|
|
17
17
|
export class Obfuscator {
|
|
18
|
+
constructor(agentRef: any);
|
|
19
|
+
agentRef: any;
|
|
20
|
+
warnedRegexMissing: boolean;
|
|
21
|
+
warnedInvalidRegex: boolean;
|
|
22
|
+
warnedInvalidReplacement: boolean;
|
|
23
|
+
get obfuscateConfigRules(): any;
|
|
18
24
|
/**
|
|
19
|
-
*
|
|
20
|
-
* @param {string}
|
|
21
|
-
* @returns {
|
|
25
|
+
* Applies all valid obfuscation rules to the provided input string
|
|
26
|
+
* @param {string} input String to obfuscate
|
|
27
|
+
* @returns {string}
|
|
22
28
|
*/
|
|
23
|
-
|
|
29
|
+
obfuscateString(input: string): string;
|
|
24
30
|
/**
|
|
25
31
|
* Validates an obfuscation rule and provides errors if any are found.
|
|
26
32
|
* @param {ObfuscationRule} rule The rule to validate
|
|
27
33
|
* @returns {ObfuscationRuleValidation} The validation state of the rule
|
|
28
34
|
*/
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Logs any obfuscation rule errors to the console. This is called when an obfuscator
|
|
32
|
-
* instance is created.
|
|
33
|
-
* @param {ObfuscationRuleValidation[]} ruleValidationCache The cache of rule validation states
|
|
34
|
-
*/
|
|
35
|
-
static logObfuscationRuleErrors(ruleValidationCache: ObfuscationRuleValidation[]): void;
|
|
36
|
-
constructor(agentIdentifier: any);
|
|
37
|
-
get ruleValidationCache(): ObfuscationRuleValidation[];
|
|
38
|
-
/**
|
|
39
|
-
* Applies all valid obfuscation rules to the provided input string
|
|
40
|
-
* @param {string} input String to obfuscate
|
|
41
|
-
* @returns {string}
|
|
42
|
-
*/
|
|
43
|
-
obfuscateString(input: string): string;
|
|
44
|
-
#private;
|
|
35
|
+
validateObfuscationRule(rule: ObfuscationRule): ObfuscationRuleValidation;
|
|
45
36
|
}
|
|
46
37
|
/**
|
|
47
38
|
* Represents an obfuscation rule that can be applied to harvested payloads
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obfuscate.d.ts","sourceRoot":"","sources":["../../../../src/common/util/obfuscate.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"obfuscate.d.ts","sourceRoot":"","sources":["../../../../src/common/util/obfuscate.js"],"names":[],"mappings":"AAGA;;;;;GAKG;AAEH;;;;;;;;;GASG;AAEH;IACE,2BAKC;IAJC,cAAwB;IACxB,4BAA+B;IAC/B,4BAA+B;IAC/B,kCAAqC;IAGvC,gCAEC;IAED;;;;OAIG;IACH,uBAHW,MAAM,GACJ,MAAM,CAoBlB;IAED;;;;OAIG;IACH,8BAHW,eAAe,GACb,yBAAyB,CA4BrC;CACF;;;;;;;;WApFa,MAAM,GAAC,MAAM;;;;;;;;;;;;;UAOb,eAAe;;;;aACf,OAAO;;;;YAElB;QAA2B,oBAAoB,EAApC,OAAO;QACS,oBAAoB,EAApC,OAAO;QACS,0BAA0B,EAA1C,OAAO;KACpB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/metrics/aggregate/index.js"],"names":[],"mappings":"AAYA;IACE,2BAAiC;IACjC,2BAoBC;IAED,iCAAsE;IAEtE,wDAKC;IAED,iDAKC;IAED,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/features/metrics/aggregate/index.js"],"names":[],"mappings":"AAYA;IACE,2BAAiC;IACjC,2BAoBC;IAED,iCAAsE;IAEtE,wDAKC;IAED,iDAKC;IAED,qBAmEC;IAED,0BAOC;CACF;8BA1H6B,4BAA4B"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@newrelic/browser-agent",
|
|
3
|
-
"version": "1.278.
|
|
3
|
+
"version": "1.278.3",
|
|
4
4
|
"private": false,
|
|
5
5
|
"author": "New Relic Browser Agent Team <browser-agent@newrelic.com>",
|
|
6
6
|
"description": "New Relic Browser Agent",
|
|
@@ -206,7 +206,7 @@
|
|
|
206
206
|
"url": "https://github.com/newrelic/newrelic-browser-agent.git"
|
|
207
207
|
},
|
|
208
208
|
"dependencies": {
|
|
209
|
-
"fflate": "0.
|
|
209
|
+
"fflate": "0.8.2",
|
|
210
210
|
"rrweb": "^2.0.0-alpha.17",
|
|
211
211
|
"web-vitals": "4.2.3"
|
|
212
212
|
},
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { getConfigurationValue } from '../config/init'
|
|
2
1
|
import { isFileProtocol } from '../url/protocol'
|
|
3
2
|
import { warn } from './console'
|
|
4
3
|
|
|
@@ -21,18 +20,15 @@ import { warn } from './console'
|
|
|
21
20
|
*/
|
|
22
21
|
|
|
23
22
|
export class Obfuscator {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
constructor (agentIdentifier) {
|
|
30
|
-
this.#ruleValidationCache = Obfuscator.getRuleValidationCache(agentIdentifier)
|
|
31
|
-
Obfuscator.logObfuscationRuleErrors(this.#ruleValidationCache)
|
|
23
|
+
constructor (agentRef) {
|
|
24
|
+
this.agentRef = agentRef
|
|
25
|
+
this.warnedRegexMissing = false
|
|
26
|
+
this.warnedInvalidRegex = false
|
|
27
|
+
this.warnedInvalidReplacement = false
|
|
32
28
|
}
|
|
33
29
|
|
|
34
|
-
get
|
|
35
|
-
return this
|
|
30
|
+
get obfuscateConfigRules () {
|
|
31
|
+
return this.agentRef.init.obfuscate || []
|
|
36
32
|
}
|
|
37
33
|
|
|
38
34
|
/**
|
|
@@ -44,24 +40,7 @@ export class Obfuscator {
|
|
|
44
40
|
// if input is not of type string or is an empty string, short-circuit
|
|
45
41
|
if (typeof input !== 'string' || input.trim().length === 0) return input
|
|
46
42
|
|
|
47
|
-
|
|
48
|
-
.filter(ruleValidation => ruleValidation.isValid)
|
|
49
|
-
.reduce((input, ruleValidation) => {
|
|
50
|
-
const { rule } = ruleValidation
|
|
51
|
-
return input.replace(rule.regex, rule.replacement || '*')
|
|
52
|
-
}, input)
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Returns an array of obfuscation rules to be applied to harvested payloads
|
|
57
|
-
* @param {string} agentIdentifier The agent identifier to get rules for
|
|
58
|
-
* @returns {ObfuscationRuleValidation[]} The array of rules or validation states
|
|
59
|
-
*/
|
|
60
|
-
static getRuleValidationCache (agentIdentifier) {
|
|
61
|
-
/**
|
|
62
|
-
* @type {ObfuscationRule[]}
|
|
63
|
-
*/
|
|
64
|
-
let rules = getConfigurationValue(agentIdentifier, 'obfuscate') || []
|
|
43
|
+
const rules = (this.obfuscateConfigRules).map(rule => this.validateObfuscationRule(rule))
|
|
65
44
|
if (isFileProtocol()) {
|
|
66
45
|
rules.push({
|
|
67
46
|
regex: /^file:\/\/(.*)/,
|
|
@@ -69,7 +48,12 @@ export class Obfuscator {
|
|
|
69
48
|
})
|
|
70
49
|
}
|
|
71
50
|
|
|
72
|
-
return rules
|
|
51
|
+
return rules
|
|
52
|
+
.filter(ruleValidation => ruleValidation.isValid)
|
|
53
|
+
.reduce((input, ruleValidation) => {
|
|
54
|
+
const { rule } = ruleValidation
|
|
55
|
+
return input.replace(rule.regex, rule.replacement || '*')
|
|
56
|
+
}, input)
|
|
73
57
|
}
|
|
74
58
|
|
|
75
59
|
/**
|
|
@@ -77,11 +61,23 @@ export class Obfuscator {
|
|
|
77
61
|
* @param {ObfuscationRule} rule The rule to validate
|
|
78
62
|
* @returns {ObfuscationRuleValidation} The validation state of the rule
|
|
79
63
|
*/
|
|
80
|
-
|
|
64
|
+
validateObfuscationRule (rule) {
|
|
81
65
|
const regexMissingDetected = Boolean(rule.regex === undefined)
|
|
82
66
|
const invalidRegexDetected = Boolean(rule.regex !== undefined && typeof rule.regex !== 'string' && !(rule.regex instanceof RegExp))
|
|
83
67
|
const invalidReplacementDetected = Boolean(rule.replacement && typeof rule.replacement !== 'string')
|
|
84
68
|
|
|
69
|
+
if (regexMissingDetected && !this.warnedRegexMissing) {
|
|
70
|
+
warn(12, rule)
|
|
71
|
+
this.warnedRegexMissing = true
|
|
72
|
+
} else if (invalidRegexDetected && !this.warnedInvalidRegex) {
|
|
73
|
+
warn(13, rule)
|
|
74
|
+
this.warnedInvalidRegex = true
|
|
75
|
+
}
|
|
76
|
+
if (invalidReplacementDetected && !this.warnedInvalidReplacement) {
|
|
77
|
+
warn(14, rule)
|
|
78
|
+
this.warnedInvalidReplacement = true
|
|
79
|
+
}
|
|
80
|
+
|
|
85
81
|
return {
|
|
86
82
|
rule,
|
|
87
83
|
isValid: !regexMissingDetected && !invalidRegexDetected && !invalidReplacementDetected,
|
|
@@ -92,20 +88,4 @@ export class Obfuscator {
|
|
|
92
88
|
}
|
|
93
89
|
}
|
|
94
90
|
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Logs any obfuscation rule errors to the console. This is called when an obfuscator
|
|
98
|
-
* instance is created.
|
|
99
|
-
* @param {ObfuscationRuleValidation[]} ruleValidationCache The cache of rule validation states
|
|
100
|
-
*/
|
|
101
|
-
static logObfuscationRuleErrors (ruleValidationCache) {
|
|
102
|
-
for (const ruleValidation of ruleValidationCache) {
|
|
103
|
-
const { rule, isValid, errors } = ruleValidation
|
|
104
|
-
if (isValid) continue
|
|
105
|
-
|
|
106
|
-
if (errors.regexMissingDetected) warn(12, rule)
|
|
107
|
-
else if (errors.invalidRegexDetected) warn(13, rule)
|
|
108
|
-
if (errors.invalidReplacementDetected) warn(14, rule)
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
91
|
}
|
|
@@ -87,10 +87,8 @@ export class Aggregate extends AggregateBase {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
// Capture SMs to assess customer engagement with the obfuscation config
|
|
90
|
-
|
|
91
|
-
if (ruleValidations.length > 0) {
|
|
90
|
+
if (this.obfuscator.obfuscateConfigRules.length > 0) {
|
|
92
91
|
this.storeSupportabilityMetrics('Generic/Obfuscate/Detected')
|
|
93
|
-
if (ruleValidations.filter(ruleValidation => !ruleValidation.isValid).length > 0) this.storeSupportabilityMetrics('Generic/Obfuscate/Invalid')
|
|
94
92
|
}
|
|
95
93
|
|
|
96
94
|
// Check if proxy for either chunks or beacon is being used
|
|
@@ -142,7 +142,7 @@ export class AggregateBase extends FeatureBase {
|
|
|
142
142
|
* This method should run after checkConfiguration, which may reset the agent's info/runtime object that is used here.
|
|
143
143
|
*/
|
|
144
144
|
doOnceForAllAggregate (agentRef) {
|
|
145
|
-
if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new Obfuscator(
|
|
145
|
+
if (!agentRef.runtime.obfuscator) agentRef.runtime.obfuscator = new Obfuscator(agentRef)
|
|
146
146
|
this.obfuscator = agentRef.runtime.obfuscator
|
|
147
147
|
|
|
148
148
|
if (!agentRef.mainAppKey) agentRef.mainAppKey = { licenseKey: agentRef.info.licenseKey, appId: agentRef.info.applicationID }
|