Skip to content

Commit

Permalink
utils: Ensure JWT redaction for error messages (#1768)
Browse files Browse the repository at this point in the history
  • Loading branch information
MicroFish91 authored Aug 15, 2024
1 parent b010f00 commit a448741
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 3 deletions.
4 changes: 2 additions & 2 deletions utils/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion utils/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@microsoft/vscode-azext-utils",
"author": "Microsoft Corporation",
"version": "2.5.5",
"version": "2.5.6",
"description": "Common UI tools for developing Azure extensions for VS Code",
"tags": [
"azure",
Expand Down
4 changes: 4 additions & 0 deletions utils/src/masking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,10 @@ export function maskUserInfo(unknownArg: unknown, actionValuesToMask: string[],
data = maskValue(data, value);
}

// Loose pattern matching to identify any JWT-like character sequences; prevents any accidental inclusions to telemetry
// The first and second JWT sections begin with "e" since the header and payload represent encoded json values that always begin with "{"
data = data.replace(/e[^\.\s]*\.e[^\.\s]*\.[^\.\s]+/gi, getRedactedLabel('jwt'));

if (!lessAggressive) {
data = data.replace(/\S+@\S+/gi, getRedactedLabel('email'));
data = data.replace(/\b[0-9a-f\-\:\.]{4,}\b/gi, getRedactedLabel('id')); // should cover guids, ip addresses, etc.
Expand Down
11 changes: 11 additions & 0 deletions utils/test/masking.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,17 @@ suite("masking", () => {
assert.strictEqual(maskUserInfo('pwd: "ddddddd!@#$%^&*()_+"', []), 'redacted:key');
});

test('jwt', () => {
const mockJwtOne: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
const mockJwtTwo: string = 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkphbmUgRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.bmgFNnfHiZ1my09OnrZaconwIkp2RH94jjJWXavLTugEsxvwCM-3IJPakw7y5-3aLLZq1eA9NxEZK0a3ZjHc2A';
const mockEmptyPayloadJwt: string = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.Et9HFtf9R3GEMA0IICOfFMVXY7kkTX1wr4qCyhIf58U';

assert.strictEqual(maskUserInfo(`Bearer ${mockJwtOne}`, []), 'Bearer redacted:jwt');
assert.strictEqual(maskUserInfo(`Empty payload jwt: ${mockEmptyPayloadJwt}`, []), 'Empty payload jwt: redacted:jwt');
assert.strictEqual(maskUserInfo(`redacted:url ${mockJwtTwo}`, []), 'redacted:url redacted:jwt');
assert.strictEqual(maskUserInfo(`This message references two jwt's: ${mockJwtOne} and ${mockJwtTwo}.`, []), 'This message references two jwt\'s: redacted:jwt and redacted:jwt.');
});

test('lessAggressive', async () => {
const valueToMask = 'valueToMask';
assert.strictEqual(maskUserInfo('https://microsoft.com c35d6342-5917-46f8-953e-9d3faffd1c72 hello@world accountkey=1234 valueToMask', [valueToMask], true /* lessAggressive */), 'redacted:url c35d6342-5917-46f8-953e-9d3faffd1c72 hello@world redacted:key ---');
Expand Down

0 comments on commit a448741

Please sign in to comment.