mirror of
https://github.com/linkwarden/linkwarden.git
synced 2026-06-28 06:45:50 +00:00
51 lines
1.7 KiB
TypeScript
51 lines
1.7 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
assertUrlIsSafeForServerSideFetch,
|
|
isHostnameBlockedForServerSideFetch,
|
|
isIpAddressBlockedForServerSideFetch,
|
|
UnsafeUrlError,
|
|
} from "./ssrf";
|
|
|
|
describe("ssrf guard", () => {
|
|
it("blocks localhost hostnames", () => {
|
|
expect(isHostnameBlockedForServerSideFetch("localhost")).toBe(true);
|
|
expect(isHostnameBlockedForServerSideFetch("subdomain.localhost")).toBe(
|
|
true
|
|
);
|
|
});
|
|
|
|
it("blocks single-label internal hostnames", () => {
|
|
expect(isHostnameBlockedForServerSideFetch("meilisearch")).toBe(true);
|
|
expect(isHostnameBlockedForServerSideFetch("postgres")).toBe(true);
|
|
});
|
|
|
|
it("blocks private and loopback IP literals", () => {
|
|
expect(isIpAddressBlockedForServerSideFetch("127.0.0.1")).toBe(true);
|
|
expect(isIpAddressBlockedForServerSideFetch("169.254.169.254")).toBe(true);
|
|
expect(isIpAddressBlockedForServerSideFetch("::1")).toBe(true);
|
|
expect(isIpAddressBlockedForServerSideFetch("fc00::1")).toBe(true);
|
|
});
|
|
|
|
it("allows public hostnames that resolve to public IPs", async () => {
|
|
await expect(
|
|
assertUrlIsSafeForServerSideFetch("https://example.com", {
|
|
lookup: async () => [{ address: "93.184.216.34", family: 4 }],
|
|
})
|
|
).resolves.toBeInstanceOf(URL);
|
|
});
|
|
|
|
it("blocks hostnames that resolve to private IPs", async () => {
|
|
await expect(
|
|
assertUrlIsSafeForServerSideFetch("https://example.com", {
|
|
lookup: async () => [{ address: "10.0.0.8", family: 4 }],
|
|
})
|
|
).rejects.toBeInstanceOf(UnsafeUrlError);
|
|
});
|
|
|
|
it("blocks IPv6 loopback literals", async () => {
|
|
await expect(
|
|
assertUrlIsSafeForServerSideFetch("http://[::1]/")
|
|
).rejects.toBeInstanceOf(UnsafeUrlError);
|
|
});
|
|
});
|