{"version":3,"file":"security.test.d.ts","sourceRoot":"","sources":["../../../src/core/web-research/security.test.ts"],"names":[],"mappings":"","sourcesContent":["import { describe, expect, it } from \"vitest\";\nimport { isBlockedWebAddress, resolveAndValidateWebUrl, validateWebUrlSyntax } from \"./security.js\";\n\ndescribe(\"web fetch SSRF policy\", () => {\n\tit.each([\n\t\t\"127.0.0.1\",\n\t\t\"0.0.0.0\",\n\t\t\"10.1.2.3\",\n\t\t\"172.16.1.2\",\n\t\t\"192.168.1.2\",\n\t\t\"169.254.169.254\",\n\t\t\"100.100.100.200\",\n\t\t\"224.0.0.1\",\n\t\t\"::1\",\n\t\t\"::\",\n\t\t\"fc00::1\",\n\t\t\"fe80::1\",\n\t\t\"ff02::1\",\n\t\t\"::ffff:127.0.0.1\",\n\t\t\"::ffff:a9fe:a9fe\",\n\t])(\"blocks non-public address %s\", (address) => {\n\t\texpect(isBlockedWebAddress(address)).toBe(true);\n\t});\n\n\tit.each([\n\t\t\"file:///etc/passwd\",\n\t\t\"data:text/plain,hi\",\n\t\t\"ftp://example.com/a\",\n\t\t\"gopher://example.com\",\n\t\t\"http://user:pass@example.com\",\n\t])(\"blocks forbidden URL %s\", (url) => expect(() => validateWebUrlSyntax(url)).toThrow());\n\n\tit.each([\"http://127.0.0.1\", \"http://[::1]\", \"http://0x7f000001\", \"http://2130706433\", \"http://0177.0.0.1\"])(\n\t\t\"blocks alternate loopback notation %s after normalization/resolution\",\n\t\tasync (url) => {\n\t\t\tawait expect(\n\t\t\t\tresolveAndValidateWebUrl(url, {\n\t\t\t\t\tresolver: async (hostname) => [\n\t\t\t\t\t\t{ address: hostname.replace(/[[\\]]/g, \"\"), family: hostname.includes(\":\") ? 6 : 4 },\n\t\t\t\t\t],\n\t\t\t\t}),\n\t\t\t).rejects.toMatchObject({ code: \"DNS_BLOCKED\" });\n\t\t},\n\t);\n\n\tit(\"blocks DNS answers when any address is private\", async () => {\n\t\tawait expect(\n\t\t\tresolveAndValidateWebUrl(\"https://public.example\", {\n\t\t\t\tresolver: async () => [\n\t\t\t\t\t{ address: \"93.184.216.34\", family: 4 },\n\t\t\t\t\t{ address: \"10.0.0.2\", family: 4 },\n\t\t\t\t],\n\t\t\t}),\n\t\t).rejects.toMatchObject({ code: \"DNS_BLOCKED\" });\n\t});\n\n\tit(\"pins and returns only the vetted DNS answer set\", async () => {\n\t\tconst answers = [\n\t\t\t{ address: \"93.184.216.34\", family: 4 },\n\t\t\t{ address: \"2606:2800:220:1:248:1893:25c8:1946\", family: 6 },\n\t\t];\n\t\tawait expect(resolveAndValidateWebUrl(\"https://example.com\", { resolver: async () => answers })).resolves.toEqual(\n\t\t\t{\n\t\t\t\turl: new URL(\"https://example.com\"),\n\t\t\t\taddresses: answers,\n\t\t\t},\n\t\t);\n\t});\n\n\tit.each([\"http://localhost\", \"http://service.internal\", \"http://metadata.google.internal\"])(\n\t\t\"blocks internal hostname %s before DNS\",\n\t\t(url) => expect(() => validateWebUrlSyntax(url)).toThrow(),\n\t);\n});\n"]}