mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 10:10:45 +00:00
test: tighten browser cdpUrl redaction coverage
This commit is contained in:
@@ -1163,59 +1163,38 @@ describe("redactConfigSnapshot", () => {
|
||||
expect(channels.slack.accounts[1].botToken).toBe(REDACTED_SENTINEL);
|
||||
});
|
||||
|
||||
it("redacts credentials embedded in browser.cdpUrl (query token and userinfo)", () => {
|
||||
it("redacts browser cdpUrl secrets while preserving bare endpoints", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const raw = `{
|
||||
browser: {
|
||||
cdpUrl: "https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
},
|
||||
}`;
|
||||
const snapshot = makeSnapshot(
|
||||
{
|
||||
browser: {
|
||||
cdpUrl: "https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
},
|
||||
},
|
||||
raw,
|
||||
);
|
||||
|
||||
const result = redactConfigSnapshot(snapshot, hints);
|
||||
const cfg = result.config as typeof snapshot.config;
|
||||
expect(cfg.browser.cdpUrl).toBe(REDACTED_SENTINEL);
|
||||
expect(result.raw).toContain(REDACTED_SENTINEL);
|
||||
expect(result.raw).not.toContain("user:pass@");
|
||||
expect(result.raw).not.toContain("supersecret123");
|
||||
|
||||
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
|
||||
expect(restored.browser.cdpUrl).toBe(
|
||||
"https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
);
|
||||
});
|
||||
|
||||
it("redacts credentials embedded in browser.profiles.*.cdpUrl", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const raw = `{
|
||||
browser: {
|
||||
profiles: {
|
||||
staging: {
|
||||
remote: {
|
||||
cdpUrl: "https://chrome.staging.example.com?token=staging-secret",
|
||||
},
|
||||
prod: {
|
||||
cdpUrl: "https://alice:secret@chrome.prod.example.com",
|
||||
},
|
||||
local: {
|
||||
cdpUrl: "ws://localhost:9222",
|
||||
},
|
||||
},
|
||||
},
|
||||
}`;
|
||||
const snapshot = makeSnapshot(
|
||||
{
|
||||
browser: {
|
||||
cdpUrl: "https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
profiles: {
|
||||
staging: {
|
||||
remote: {
|
||||
cdpUrl: "https://chrome.staging.example.com?token=staging-secret",
|
||||
},
|
||||
prod: {
|
||||
cdpUrl: "https://alice:secret@chrome.prod.example.com",
|
||||
},
|
||||
local: {
|
||||
cdpUrl: "ws://localhost:9222",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -1224,34 +1203,26 @@ describe("redactConfigSnapshot", () => {
|
||||
|
||||
const result = redactConfigSnapshot(snapshot, hints);
|
||||
const cfg = result.config as typeof snapshot.config;
|
||||
expect(cfg.browser.profiles.staging.cdpUrl).toBe(REDACTED_SENTINEL);
|
||||
expect(cfg.browser.cdpUrl).toBe(REDACTED_SENTINEL);
|
||||
expect(cfg.browser.profiles.remote.cdpUrl).toBe(REDACTED_SENTINEL);
|
||||
expect(cfg.browser.profiles.prod.cdpUrl).toBe(REDACTED_SENTINEL);
|
||||
expect(cfg.browser.profiles.local.cdpUrl).toBe("ws://localhost:9222");
|
||||
expect(result.raw).toContain(REDACTED_SENTINEL);
|
||||
expect(result.raw).not.toContain("user:pass@");
|
||||
expect(result.raw).not.toContain("supersecret123");
|
||||
expect(result.raw).not.toContain("staging-secret");
|
||||
expect(result.raw).not.toContain("alice:secret@");
|
||||
|
||||
const restored = restoreRedactedValues(result.config, snapshot.config, hints);
|
||||
expect(restored.browser.profiles.staging.cdpUrl).toBe(
|
||||
expect(restored.browser.cdpUrl).toBe(
|
||||
"https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
);
|
||||
expect(restored.browser.profiles.remote.cdpUrl).toBe(
|
||||
"https://chrome.staging.example.com?token=staging-secret",
|
||||
);
|
||||
expect(restored.browser.profiles.prod.cdpUrl).toBe(
|
||||
"https://alice:secret@chrome.prod.example.com",
|
||||
);
|
||||
});
|
||||
|
||||
it("does not redact bare cdpUrl addresses without credentials", () => {
|
||||
const hints = buildConfigSchema().uiHints;
|
||||
const snapshot = makeSnapshot({
|
||||
browser: {
|
||||
cdpUrl: "http://10.0.0.42:9222",
|
||||
profiles: {
|
||||
local: { cdpUrl: "ws://localhost:9222" },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const result = redactConfigSnapshot(snapshot, hints);
|
||||
const cfg = result.config as typeof snapshot.config;
|
||||
expect(cfg.browser.cdpUrl).toBe("http://10.0.0.42:9222");
|
||||
expect(cfg.browser.profiles.local.cdpUrl).toBe("ws://localhost:9222");
|
||||
expect(restored.browser.profiles.local.cdpUrl).toBe("ws://localhost:9222");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -157,6 +157,62 @@ describe("gateway config methods", () => {
|
||||
expect(res.payload?.config).toBeTruthy();
|
||||
});
|
||||
|
||||
it("redacts browser cdpUrl credentials from config.get responses", async () => {
|
||||
const { createConfigIO, resetConfigRuntimeState } = await import("../config/config.js");
|
||||
const configPath = createConfigIO().configPath;
|
||||
await fs.mkdir(path.dirname(configPath), { recursive: true });
|
||||
try {
|
||||
await fs.writeFile(
|
||||
configPath,
|
||||
`${JSON.stringify(
|
||||
{
|
||||
browser: {
|
||||
cdpUrl: "https://user:pass@chrome.browserless.io?token=supersecret123",
|
||||
profiles: {
|
||||
remote: {
|
||||
cdpUrl: "https://alice:secret@chrome.remote.example.com?token=profile-secret",
|
||||
},
|
||||
local: {
|
||||
cdpUrl: "ws://127.0.0.1:9222",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
null,
|
||||
2,
|
||||
)}\n`,
|
||||
"utf-8",
|
||||
);
|
||||
resetConfigRuntimeState();
|
||||
|
||||
const after = await rpcReq<{
|
||||
raw?: string | null;
|
||||
config?: {
|
||||
browser?: {
|
||||
cdpUrl?: string;
|
||||
profiles?: Record<string, { cdpUrl?: string }>;
|
||||
};
|
||||
};
|
||||
}>(requireWs(), "config.get", {});
|
||||
expect(after.ok).toBe(true);
|
||||
expect(after.payload?.config?.browser?.cdpUrl).toBe("__OPENCLAW_REDACTED__");
|
||||
expect(after.payload?.config?.browser?.profiles?.remote?.cdpUrl).toBe(
|
||||
"__OPENCLAW_REDACTED__",
|
||||
);
|
||||
expect(after.payload?.config?.browser?.profiles?.local?.cdpUrl).toBe("ws://127.0.0.1:9222");
|
||||
if (typeof after.payload?.raw === "string") {
|
||||
expect(after.payload.raw).toContain("__OPENCLAW_REDACTED__");
|
||||
expect(after.payload.raw).not.toContain("supersecret123");
|
||||
expect(after.payload.raw).not.toContain("user:pass@");
|
||||
expect(after.payload.raw).not.toContain("profile-secret");
|
||||
expect(after.payload.raw).not.toContain("alice:secret@");
|
||||
}
|
||||
} finally {
|
||||
await fs.rm(configPath, { force: true });
|
||||
resetConfigRuntimeState();
|
||||
}
|
||||
});
|
||||
|
||||
it("does not reject config.set for unresolved auth-profile refs outside submitted config", async () => {
|
||||
const missingEnvVar = `OPENCLAW_MISSING_AUTH_PROFILE_REF_${Date.now()}`;
|
||||
await writeUnresolvedAuthProfileTokenRef(missingEnvVar);
|
||||
|
||||
Reference in New Issue
Block a user