mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:10:45 +00:00
refactor: reuse support redaction classifiers
This commit is contained in:
@@ -384,6 +384,14 @@ describe("diagnostic support export", () => {
|
||||
"connect wss://support-user:support-password@gateway.example/ws?token=short-token&ok=1",
|
||||
"connect wss://<redacted>:<redacted>@gateway.example/ws?token=<redacted>",
|
||||
],
|
||||
[
|
||||
"connect https://gateway.example/ws?access-token=short-token",
|
||||
"connect https://gateway.example/ws?access-token=<redacted>",
|
||||
],
|
||||
[
|
||||
"connect https://gateway.example/ws?hook-token=hook-secret",
|
||||
"connect https://gateway.example/ws?hook-token=<redacted>",
|
||||
],
|
||||
["connect https://token@gateway.example/ws", "connect https://<redacted>@gateway.example/ws"],
|
||||
["auth Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ==", "auth Basic <redacted>"],
|
||||
["Cookie: sid=secret; theme=light", "Cookie: <redacted>"],
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import path from "node:path";
|
||||
import { isSecretRefShape } from "../config/redact-snapshot.secret-ref.js";
|
||||
import { isSensitiveUrlQueryParamName } from "../shared/net/redact-sensitive-url.js";
|
||||
import { redactSensitiveText } from "./redact.js";
|
||||
|
||||
const SECRET_SUPPORT_FIELD_RE =
|
||||
@@ -17,8 +19,7 @@ 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 SENSITIVE_URL_PARAM_RE =
|
||||
/([?&](?:api[-_]?key|access[-_]?token|auth[-_]?token|hook[-_]?token|password|passwd|refresh[-_]?token|secret|token)=)[^&#\s]+/giu;
|
||||
const URL_PARAM_RE = /([?&])([^=&\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;
|
||||
@@ -58,10 +59,6 @@ function isPrivateConfigField(key: string): boolean {
|
||||
return isPrivateSupportField(key) || CONFIG_PRIVATE_FIELD_RE.test(key);
|
||||
}
|
||||
|
||||
function isSecretRefShape(value: Record<string, unknown>): boolean {
|
||||
return typeof value.source === "string" && typeof value.id === "string";
|
||||
}
|
||||
|
||||
function sanitizeSecretRefForSupport(value: Record<string, unknown>): Record<string, unknown> {
|
||||
const sanitized: Record<string, unknown> = {};
|
||||
if (typeof value.source === "string") {
|
||||
@@ -143,7 +140,9 @@ function redactUrlSecretsForSupport(value: string): string {
|
||||
.replace(URL_USERINFO_RE, (_match, scheme: string, _username: string, password?: string) =>
|
||||
password ? `${scheme}<redacted>:<redacted>@` : `${scheme}<redacted>@`,
|
||||
)
|
||||
.replace(SENSITIVE_URL_PARAM_RE, "$1<redacted>");
|
||||
.replace(URL_PARAM_RE, (match, prefix: string, key: string) =>
|
||||
isSensitiveUrlQueryParamName(key) ? `${prefix}${key}=<redacted>` : match,
|
||||
);
|
||||
}
|
||||
|
||||
function redactContactIdentifiersForSupport(value: string): string {
|
||||
|
||||
@@ -48,6 +48,9 @@ describe("isSensitiveUrlQueryParamName", () => {
|
||||
it("matches the auth-oriented query params used by MCP SSE config redaction", () => {
|
||||
expect(isSensitiveUrlQueryParamName("token")).toBe(true);
|
||||
expect(isSensitiveUrlQueryParamName("refresh_token")).toBe(true);
|
||||
expect(isSensitiveUrlQueryParamName("access-token")).toBe(true);
|
||||
expect(isSensitiveUrlQueryParamName("hook-token")).toBe(true);
|
||||
expect(isSensitiveUrlQueryParamName("passwd")).toBe(true);
|
||||
expect(isSensitiveUrlQueryParamName("signature")).toBe(true);
|
||||
expect(isSensitiveUrlQueryParamName("safe")).toBe(false);
|
||||
});
|
||||
|
||||
@@ -10,16 +10,20 @@ const SENSITIVE_URL_QUERY_PARAM_NAMES = new Set([
|
||||
"apikey",
|
||||
"secret",
|
||||
"access_token",
|
||||
"auth_token",
|
||||
"password",
|
||||
"pass",
|
||||
"passwd",
|
||||
"auth",
|
||||
"client_secret",
|
||||
"hook_token",
|
||||
"refresh_token",
|
||||
"signature",
|
||||
]);
|
||||
|
||||
export function isSensitiveUrlQueryParamName(name: string): boolean {
|
||||
return SENSITIVE_URL_QUERY_PARAM_NAMES.has(normalizeLowercaseStringOrEmpty(name));
|
||||
const normalized = normalizeLowercaseStringOrEmpty(name).replaceAll("-", "_");
|
||||
return SENSITIVE_URL_QUERY_PARAM_NAMES.has(normalized);
|
||||
}
|
||||
|
||||
export function isSensitiveUrlConfigPath(path: string): boolean {
|
||||
|
||||
Reference in New Issue
Block a user