mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix: redact URL query credentials in diagnostics
This commit is contained in:
@@ -20,7 +20,8 @@ const COOKIE_HEADER_RE = /\b(Cookie|Set-Cookie)\s*:\s*[^\r\n]+/giu;
|
||||
const AWS_ACCESS_KEY_ID_RE = /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/gu;
|
||||
const JWT_RE = /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/gu;
|
||||
const URL_USERINFO_RE = /\b([a-z][a-z0-9+.-]*:\/\/)([^/@\s:?#]+)(?::([^/@\s?#]+))?@/giu;
|
||||
const URL_PARAM_RE = /([?&])([^=&\s]+)=([^&#\s]+)/giu;
|
||||
const URL_SENSITIVE_PARAM_RE =
|
||||
/([?&])(api[-_]?key|apikey|access[-_]?token|auth[-_]?token|client[-_]?secret|hook[-_]?token|refresh[-_]?token|token|key|secret|password|pass|passwd|auth|signature)=([^&#\s)"'<>]+)(?:&[^#\s)"'<>]*)?/giu;
|
||||
const EMAIL_RE = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/giu;
|
||||
const MATRIX_USER_ID_RE = /@[A-Za-z0-9._=-]+:[A-Za-z0-9.-]+/gu;
|
||||
const MATRIX_ROOM_ID_RE = /![A-Za-z0-9._=-]+:[A-Za-z0-9.-]+/gu;
|
||||
@@ -306,7 +307,7 @@ function redactUrlSecretsForSupport(value: string): string {
|
||||
.replace(URL_USERINFO_RE, (_match, scheme: string, _username: string, password?: string) =>
|
||||
password ? `${scheme}<redacted>:<redacted>@` : `${scheme}<redacted>@`,
|
||||
)
|
||||
.replace(URL_PARAM_RE, (match, prefix: string, key: string) =>
|
||||
.replace(URL_SENSITIVE_PARAM_RE, (match, prefix: string, key: string) =>
|
||||
isSensitiveUrlQueryParamName(key) ? `${prefix}${key}=<redacted>` : match,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -61,6 +61,24 @@ describe("redactSensitiveText", () => {
|
||||
expect(output).toBe("gog gmail watch serve --hook-token abcdef…ghij");
|
||||
});
|
||||
|
||||
it("masks sensitive URL query parameters", () => {
|
||||
const input = "connect https://user.example/sync?access_token=abcdef1234567890ghij&safe=value";
|
||||
const output = redactSensitiveText(input, {
|
||||
mode: "tools",
|
||||
patterns: defaults,
|
||||
});
|
||||
expect(output).toBe("connect https://user.example/sync?access_token=abcdef…ghij&safe=value");
|
||||
});
|
||||
|
||||
it("masks short URL query tokens fully", () => {
|
||||
const input = "cdp=https://browserless.example.com/?token=supersecret123";
|
||||
const output = redactSensitiveText(input, {
|
||||
mode: "tools",
|
||||
patterns: defaults,
|
||||
});
|
||||
expect(output).toBe("cdp=https://browserless.example.com/?token=***");
|
||||
});
|
||||
|
||||
it("masks JSON fields", () => {
|
||||
const input = '{"token":"abcdef1234567890ghij"}';
|
||||
const output = redactSensitiveText(input, {
|
||||
|
||||
@@ -18,6 +18,8 @@ const DEFAULT_REDACT_PATTERNS: string[] = [
|
||||
String.raw`"(?:apiKey|token|secret|password|passwd|accessToken|refreshToken)"\s*:\s*"([^"]+)"`,
|
||||
// CLI flags.
|
||||
String.raw`--(?:api[-_]?key|hook[-_]?token|token|secret|password|passwd)\s+(["']?)([^\s"']+)\1`,
|
||||
// URL query credentials.
|
||||
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`,
|
||||
// Authorization headers.
|
||||
String.raw`Authorization\s*[:=]\s*Bearer\s+([A-Za-z0-9._\-+=]+)`,
|
||||
String.raw`\bBearer\s+([A-Za-z0-9._\-+=]{18,})\b`,
|
||||
|
||||
Reference in New Issue
Block a user