Skip to content

Commit 62ab9fb

Browse files
authored
feat: Add support for filtering username/password URL authority. (#751)
1 parent 7ab6797 commit 62ab9fb

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

packages/telemetry/browser-telemetry/__tests__/filters/defaultUrlFilter.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,27 @@ it.each([
3939
])('passes through other URLs unfiltered', (url) => {
4040
expect(defaultUrlFilter(url)).toBe(url);
4141
});
42+
43+
it('filters out username and password from URLs', () => {
44+
const urls = [
45+
// Username only
46+
{
47+
input: 'https://[email protected]/',
48+
expected: 'https://[email protected]/',
49+
},
50+
// Password only
51+
{
52+
input: 'https://:[email protected]/',
53+
expected: 'https://:[email protected]/',
54+
},
55+
// Both username and password
56+
{
57+
input: 'https://user:[email protected]/',
58+
expected: 'https://redacted:[email protected]/',
59+
},
60+
];
61+
62+
urls.forEach(({ input, expected }) => {
63+
expect(defaultUrlFilter(input)).toBe(expected);
64+
});
65+
});

packages/telemetry/browser-telemetry/src/filters/defaultUrlFilter.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,43 @@
11
const pollingRegex = /sdk\/evalx\/[^/]+\/contexts\/(?<context>[^/?]*)\??.*?/;
22
const streamingREgex = /\/eval\/[^/]+\/(?<context>[^/?]*)\??.*?/;
33

4+
/**
5+
* Filter which redacts user information (auth) from a URL.
6+
*
7+
* If a username/password is present, then they are replaced with 'redacted'.
8+
* Authority reference: https://developer.mozilla.org/en-US/docs/Web/URI/Authority
9+
*
10+
* @param url URL to filter.
11+
* @returns A filtered URL.
12+
*/
13+
function authorityUrlFilter(url: string): string {
14+
// This will work in browser environments, but in the future we may want to consider an approach
15+
// which doesn't rely on the browser's URL parsing. This is because other environments we may
16+
// want to target, such as ReactNative, may not have as robust URL parsing.
17+
const urlObj = new URL(url);
18+
let hadAuth = false;
19+
if (urlObj.username) {
20+
urlObj.username = 'redacted';
21+
hadAuth = true;
22+
}
23+
if (urlObj.password) {
24+
urlObj.password = 'redacted';
25+
hadAuth = true;
26+
}
27+
if (hadAuth) {
28+
return urlObj.toString();
29+
}
30+
// If there was no auth information, then we don't need to modify the URL.
31+
return url;
32+
}
33+
434
/**
535
* Filter which removes context information for browser JavaScript endpoints.
636
*
737
* @param url URL to filter.
838
* @returns A filtered URL.
939
*/
10-
export default function defaultUrlFilter(url: string): string {
40+
function ldUrlFilter(url: string): string {
1141
// TODO: Maybe we consider a way to identify LD requests so they can be filtered without
1242
// regular expressions.
1343

@@ -27,3 +57,13 @@ export default function defaultUrlFilter(url: string): string {
2757
}
2858
return url;
2959
}
60+
61+
/**
62+
* Filter which redacts user information and removes context information for browser JavaScript endpoints.
63+
*
64+
* @param url URL to filter.
65+
* @returns A filtered URL.
66+
*/
67+
export default function defaultUrlFilter(url: string): string {
68+
return ldUrlFilter(authorityUrlFilter(url));
69+
}

0 commit comments

Comments
 (0)