From 7cc6add9b8eca528de7fae7db6f419900f80f449 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sat, 14 Feb 2026 18:53:05 +0100 Subject: [PATCH] test(web): add SSRF guard cases --- src/web/media.test.ts | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/web/media.test.ts b/src/web/media.test.ts index 0fa4146b4..594b6d8e7 100644 --- a/src/web/media.test.ts +++ b/src/web/media.test.ts @@ -163,6 +163,28 @@ describe("web media loading", () => { fetchMock.mockRestore(); }); + it("blocks private network URL fetches (SSRF guard)", async () => { + const fetchMock = vi.spyOn(globalThis, "fetch"); + + await expect(loadWebMedia("http://127.0.0.1:8080/internal-api", 1024 * 1024)).rejects.toThrow( + /blocked|private|internal/i, + ); + expect(fetchMock).not.toHaveBeenCalled(); + + fetchMock.mockRestore(); + }); + + it("blocks cloud metadata hostnames (SSRF guard)", async () => { + const fetchMock = vi.spyOn(globalThis, "fetch"); + + await expect( + loadWebMedia("http://metadata.google.internal/computeMetadata/v1/", 1024 * 1024), + ).rejects.toThrow(/blocked|private|internal|metadata/i); + expect(fetchMock).not.toHaveBeenCalled(); + + fetchMock.mockRestore(); + }); + it("respects maxBytes for raw URL fetches", async () => { const fetchMock = vi.spyOn(globalThis, "fetch").mockResolvedValueOnce({ ok: true,