diff --git a/CHANGELOG.md b/CHANGELOG.md index 97775abc61b..d5f68b1a42d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ Docs: https://docs.openclaw.ai - Gateway/Security: require secure context and paired-device checks for Control UI auth even when `gateway.controlUi.allowInsecureAuth` is set, and align audit messaging with the hardened behavior. (#20684) thanks @coygeek. - Docker/Security: run E2E and install-sh test images as non-root by adding appuser directives. Thanks @thewilloftheshadow. - Skills/Security: sanitize skill env overrides to block unsafe runtime injection variables and only allow sensitive keys when declared in skill metadata, with warnings for suspicious values. Thanks @thewilloftheshadow. +- Security/Browser: block non-network browser navigation protocols (including `file:`, `data:`, and `javascript:`) while preserving `about:blank`, preventing local file reads via browser tool navigation. This ships in the next npm release. Thanks @q1uf3ng for reporting. - Security/Gateway/Hooks: block `__proto__`, `constructor`, and `prototype` traversal in webhook template path resolution to prevent prototype-chain payload data leakage in `messageTemplate` rendering. (#22213) Thanks @SleuthCo. - Security/OpenClawKit/UI: prevent injected inbound user context metadata blocks from leaking into chat history in TUI, webchat, and macOS surfaces by stripping all untrusted metadata prefixes at display boundaries. (#22142) Thanks @Mellowambience, @vincentkoc. - Security/OpenClawKit/UI: strip inbound metadata blocks from user messages in TUI rendering while preserving user-authored content. (#22345) Thanks @kansodata, @vincentkoc. diff --git a/src/browser/navigation-guard.test.ts b/src/browser/navigation-guard.test.ts index efa07be6390..3a096aac8d9 100644 --- a/src/browser/navigation-guard.test.ts +++ b/src/browser/navigation-guard.test.ts @@ -19,7 +19,7 @@ describe("browser navigation guard", () => { ).rejects.toBeInstanceOf(SsrFBlockedError); }); - it("allows non-network schemes", async () => { + it("allows about:blank", async () => { await expect( assertBrowserNavigationAllowed({ url: "about:blank", @@ -27,6 +27,38 @@ describe("browser navigation guard", () => { ).resolves.toBeUndefined(); }); + it("blocks file URLs", async () => { + await expect( + assertBrowserNavigationAllowed({ + url: "file:///etc/passwd", + }), + ).rejects.toBeInstanceOf(InvalidBrowserNavigationUrlError); + }); + + it("blocks data URLs", async () => { + await expect( + assertBrowserNavigationAllowed({ + url: "data:text/html,