From f7a999276bb21ac8cad8674304ccbecae436d4ac Mon Sep 17 00:00:00 2001 From: OpenClaw Subagent Date: Sun, 15 Mar 2026 11:13:49 +0100 Subject: [PATCH] test: add HTTP rewrite and block-other-host SSRF branch tests for browser.ts --- src/__tests__/browser-coverage.test.ts | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/__tests__/browser-coverage.test.ts b/src/__tests__/browser-coverage.test.ts index b6fd69b..5be3b3b 100644 --- a/src/__tests__/browser-coverage.test.ts +++ b/src/__tests__/browser-coverage.test.ts @@ -149,6 +149,55 @@ describe("browser-coverage: HTTPS request interception", () => { expect(httpsRequest.continue).toHaveBeenCalledWith(); expect(httpsRequest.abort).not.toHaveBeenCalled(); }); + + it("rewrites HTTP requests to target host with IP substitution", async () => { + await browserModule.initBrowser(); + await browserModule.renderUrlPdf("http://example.com", { + hostResolverRules: "MAP example.com 93.184.216.34", + }); + + const usedPage = mockBrowsers + .flatMap((b: any) => b._pages.slice(0, 2)) + .find((p: any) => p.on.mock.calls.length > 0); + + const requestHandler = usedPage.on.mock.calls.find((c: any) => c[0] === "request")[1]; + + const httpRequest = { + url: () => "http://example.com/page", + headers: () => ({ accept: "text/html" }), + abort: vi.fn(), + continue: vi.fn(), + }; + requestHandler(httpRequest); + expect(httpRequest.continue).toHaveBeenCalledWith(expect.objectContaining({ + url: expect.stringContaining("93.184.216.34"), + headers: expect.objectContaining({ host: "example.com" }), + })); + expect(httpRequest.abort).not.toHaveBeenCalled(); + }); + + it("blocks requests to non-target hosts (SSRF redirect prevention)", async () => { + await browserModule.initBrowser(); + await browserModule.renderUrlPdf("http://example.com", { + hostResolverRules: "MAP example.com 93.184.216.34", + }); + + const usedPage = mockBrowsers + .flatMap((b: any) => b._pages.slice(0, 2)) + .find((p: any) => p.on.mock.calls.length > 0); + + const requestHandler = usedPage.on.mock.calls.find((c: any) => c[0] === "request")[1]; + + const evilRequest = { + url: () => "http://evil.com/steal", + headers: () => ({}), + abort: vi.fn(), + continue: vi.fn(), + }; + requestHandler(evilRequest); + expect(evilRequest.abort).toHaveBeenCalledWith("blockedbyclient"); + expect(evilRequest.continue).not.toHaveBeenCalled(); + }); }); describe("browser-coverage: releasePage error paths", () => {