diff --git a/src/browser/CdpCaptureDocuments.baseUrl.test.ts b/src/browser/CdpCaptureDocuments.baseUrl.test.ts index c2c9378b89..94b04dc65b 100644 --- a/src/browser/CdpCaptureDocuments.baseUrl.test.ts +++ b/src/browser/CdpCaptureDocuments.baseUrl.test.ts @@ -100,6 +100,44 @@ describe("DOM metadata document base URLs", () => { }); }); + it.each([ + "javascript:void(0)", + "mailto:someone@example.test", + "data:text/plain,hello", + "ftp://app.example.test/file", + ])("classifies the non-http(s) destination %s as unsupported", (href) => { + const result = capture(snapshot(undefined, "assets/", documentUrl, href)); + expect(result.urls[1]).toMatchObject({ + url: null, + destination_scope: "unsupported", + }); + }); + + it("classifies an unparseable destination as unsupported", () => { + const result = capture( + snapshot(undefined, "assets/", documentUrl, "https://[invalid"), + ); + expect(result.urls[1]).toMatchObject({ + url: null, + destination_scope: "unsupported", + }); + }); + + it("classifies a same-origin destination with credentials as approved", () => { + const result = capture( + snapshot( + undefined, + "assets/", + documentUrl, + "https://user:secret@app.example.test/guide", + ), + ); + expect(result.urls[1]).toMatchObject({ + url: `${origin}/guide`, + destination_scope: "approved", + }); + }); + it("does not authorize a foreign document using its approved base URL", () => { const result = capture( snapshot( diff --git a/tests/boundary/browser/webSourceMapFetcher.test.ts b/tests/boundary/browser/webSourceMapFetcher.test.ts index 7d251b41ad..2ce7903a3c 100644 --- a/tests/boundary/browser/webSourceMapFetcher.test.ts +++ b/tests/boundary/browser/webSourceMapFetcher.test.ts @@ -193,6 +193,37 @@ describe("web source-map fetching and validation: fetching maps and following re }); }); + it.each([ + ["embedded credentials", "https://user:secret@app.example.test/a.map"], + ["a different scheme on the same host", "http://app.example.test/a.map"], + ["another origin", "https://private.example.test/a.map"], + ["a non-http(s) scheme", "ftp://app.example.test/a.map"], + ["a file URL", "file:///tmp/a.map"], + ["an unparseable URL", "not a url"], + ])( + "filters a declared fetch URL with %s before any request", + async (_description, fetchUrl) => { + const calls: string[] = []; + const result = await fetchWebSourceMaps( + [{ ...request, fetchUrl }], + input(), + undefined, + { + fetch: (url) => { + calls.push(String(url)); + return Promise.resolve(new Response("{}", { status: 200 })); + }, + }, + ); + + expect(calls).toEqual([]); + expect(result).toMatchObject({ + status: "unavailable", + items: [{ status: "policy_filtered" }], + }); + }, + ); + it("follows an approved redirect chain without an arbitrary hop ceiling", async () => { const calls: string[] = []; const result = await fetchWebSourceMaps([request], input(), undefined, {