Skip to content

Commit e7432ae

Browse files
committed
fix: redact URL query credentials in diagnostics
1 parent d33eebd commit e7432ae

3 files changed

Lines changed: 23 additions & 2 deletions

File tree

src/logging/diagnostic-support-redaction.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ const COOKIE_HEADER_RE = /\b(Cookie|Set-Cookie)\s*:\s*[^\r\n]+/giu;
2020
const AWS_ACCESS_KEY_ID_RE = /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/gu;
2121
const JWT_RE = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/gu;
2222
const URL_USERINFO_RE = /\b([a-z][a-z0-9+.-]*:\/\/)([^/@\s:?#]+)(?::([^/@\s?#]+))?@/giu;
23-
const URL_PARAM_RE = /([?&])([^=&\s]+)=([^&#\s]+)/giu;
23+
const URL_SENSITIVE_PARAM_RE =
24+
/([?&])(api[-_]?key|apikey|access[-_]?token|auth[-_]?token|client[-_]?secret|hook[-_]?token|refresh[-_]?token|token|key|secret|password|pass|passwd|auth|signature)=([^&#\s)"'<>]+)(?:&[^#\s)"'<>]*)?/giu;
2425
const EMAIL_RE = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/giu;
2526
const MATRIX_USER_ID_RE = /@[A-Za-z0-9._=-]+:[A-Za-z0-9.-]+/gu;
2627
const MATRIX_ROOM_ID_RE = /![A-Za-z0-9._=-]+:[A-Za-z0-9.-]+/gu;
@@ -306,7 +307,7 @@ function redactUrlSecretsForSupport(value: string): string {
306307
.replace(URL_USERINFO_RE, (_match, scheme: string, _username: string, password?: string) =>
307308
password ? `${scheme}<redacted>:<redacted>@` : `${scheme}<redacted>@`,
308309
)
309-
.replace(URL_PARAM_RE, (match, prefix: string, key: string) =>
310+
.replace(URL_SENSITIVE_PARAM_RE, (match, prefix: string, key: string) =>
310311
isSensitiveUrlQueryParamName(key) ? `${prefix}${key}=<redacted>` : match,
311312
);
312313
}

src/logging/redact.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,24 @@ describe("redactSensitiveText", () => {
6161
expect(output).toBe("gog gmail watch serve --hook-token abcdef…ghij");
6262
});
6363

64+
it("masks sensitive URL query parameters", () => {
65+
const input = "connect https://user.example/sync?access_token=abcdef1234567890ghij&safe=value";
66+
const output = redactSensitiveText(input, {
67+
mode: "tools",
68+
patterns: defaults,
69+
});
70+
expect(output).toBe("connect https://user.example/sync?access_token=abcdef…ghij&safe=value");
71+
});
72+
73+
it("masks short URL query tokens fully", () => {
74+
const input = "cdp=https://browserless.example.com/?token=supersecret123";
75+
const output = redactSensitiveText(input, {
76+
mode: "tools",
77+
patterns: defaults,
78+
});
79+
expect(output).toBe("cdp=https://browserless.example.com/?token=***");
80+
});
81+
6482
it("masks JSON fields", () => {
6583
const input = '{"token":"abcdef1234567890ghij"}';
6684
const output = redactSensitiveText(input, {

src/logging/redact.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ const DEFAULT_REDACT_PATTERNS: string[] = [
1818
String.raw`"(?:apiKey|token|secret|password|passwd|accessToken|refreshToken)"\s*:\s*"([^"]+)"`,
1919
// CLI flags.
2020
String.raw`--(?:api[-_]?key|hook[-_]?token|token|secret|password|passwd)\s+(["']?)([^\s"']+)\1`,
21+
// URL query credentials.
22+
String.raw`/([?&](?:api[-_]?key|apikey|access[-_]?token|auth[-_]?token|client[-_]?secret|hook[-_]?token|refresh[-_]?token|token|key|secret|password|pass|passwd|auth|signature)=)([^&#\s)"'<>]+)/giu`,
2123
// Authorization headers.
2224
String.raw`Authorization\s*[:=]\s*Bearer\s+([A-Za-z0-9._\-+=]+)`,
2325
String.raw`\bBearer\s+([A-Za-z0-9._\-+=]{18,})\b`,

0 commit comments

Comments
 (0)