Files
PaperClipAI/server/src/__tests__/remote-http-endpoint-guard.test.ts
T
Devin FoleyandPaperclip 3d0e74e743 Keep proven external connection failures out of Sentry (#15590)
Apply the reviewed change for Keep proven external connection failures out of Sentry.

Validation: local typecheck/build and focused regression tests, passing exact-head CI, Greptile 5/5, and independent source review. The PR records full-suite evidence and any local environment limitations.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 10:19:40 -07:00

99 lines
4.1 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { assertPublicRemoteHttpEndpoint } from "../services/remote-http-endpoint-guard.js";
import { readRemoteConnectionFailure } from "../services/remote-connection-failure.js";
function guardError(message: string, code: string) {
return Object.assign(new Error(message), { code });
}
describe("remote HTTP endpoint guard", () => {
it.each(["ENOTFOUND", "ENODATA", "EAI_AGAIN"])("retains proven DNS failure %s across the public wrapper", async (code) => {
const failure = await assertPublicRemoteHttpEndpoint(new URL("https://missing.example.test/mcp"), {
lookup: async () => { throw Object.assign(new Error("lookup failed"), { code }); },
}, guardError).catch((error) => error);
expect(failure).toMatchObject({ code: "remote_http_dns_failed" });
expect(readRemoteConnectionFailure(failure)).toBe("dns_failure");
});
it("marks its exact DNS deadline without trusting unknown lookup exceptions", async () => {
const timedOut = await assertPublicRemoteHttpEndpoint(new URL("https://silent.example.test/mcp"), {
lookup: async () => new Promise(() => {}), dnsTimeoutMs: 1,
}, guardError).catch((error) => error);
expect(timedOut).toMatchObject({ code: "remote_http_dns_failed" });
expect(readRemoteConnectionFailure(timedOut)).toBe("connection_timeout");
const unknown = await assertPublicRemoteHttpEndpoint(new URL("https://broken.example.test/mcp"), {
lookup: async () => { throw new TypeError("internal lookup bug: ENOTFOUND"); },
}, guardError).catch((error) => error);
expect(unknown).toMatchObject({ code: "remote_http_dns_failed" });
expect(readRemoteConnectionFailure(unknown)).toBeNull();
});
it("blocks hostnames that resolve to private network addresses", async () => {
await expect(assertPublicRemoteHttpEndpoint(
new URL("https://metadata.example/mcp"),
{ lookup: async () => [{ address: "10.0.0.12", family: 4 }] },
guardError,
)).rejects.toMatchObject({ code: "remote_http_private_endpoint" });
});
it("allows hostnames when every resolved address is public", async () => {
await expect(assertPublicRemoteHttpEndpoint(
new URL("https://public.example/mcp"),
{ lookup: async () => [{ address: "93.184.216.34", family: 4 }] },
guardError,
)).resolves.toBeUndefined();
});
it.each([
"169.254.0.1",
"169.254.169.254",
"::ffff:169.254.169.254",
"::ffff:a9fe:a9fe",
"fe80::1",
"febf::1",
])("always rejects link-local literal %s when private networking is allowed", async (address) => {
const url = address.includes(":") ? `http://[${address}]/mcp` : `http://${address}/mcp`;
await expect(assertPublicRemoteHttpEndpoint(
new URL(url),
{ allowPrivateNetwork: true },
guardError,
)).rejects.toMatchObject({ code: "remote_http_private_endpoint" });
});
it.each(["169.254.42.1", "fe80::1234"])(
"always rejects link-local DNS answer %s when private networking is allowed",
async (address) => {
await expect(assertPublicRemoteHttpEndpoint(
new URL("https://operator-endpoint.example/mcp"),
{ allowPrivateNetwork: true, lookup: async () => [{ address, family: address.includes(":") ? 6 : 4 }] },
guardError,
)).rejects.toMatchObject({ code: "remote_http_private_endpoint" });
},
);
it.each(["127.0.0.1", "10.1.2.3", "fd00::1"])(
"allows intended private address %s when private networking is allowed",
async (address) => {
const url = address.includes(":") ? `http://[${address}]/mcp` : `http://${address}/mcp`;
await expect(assertPublicRemoteHttpEndpoint(
new URL(url),
{ allowPrivateNetwork: true },
guardError,
)).resolves.toBeUndefined();
},
);
it.each([
"http://[2001::1]/mcp",
"http://[2001:20::1]/mcp",
"http://[2001:2f::1]/mcp",
"http://[64:ff9b:1::1]/mcp",
])("rejects reserved IPv6 endpoint %s", async (url) => {
await expect(assertPublicRemoteHttpEndpoint(
new URL(url),
{},
guardError,
)).rejects.toMatchObject({ code: "remote_http_private_endpoint" });
});
});