Laimiao agent v2 service: agent orchestration, sessions, billing, gateway client, skills catalog, auth, config, plus tests.
136 lines
4.3 KiB
TypeScript
136 lines
4.3 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
assertSafeUrl,
|
|
hostMatches,
|
|
isBlockedAddress,
|
|
isBlockedHostname,
|
|
parseHostAllowlist,
|
|
safeFetch,
|
|
} from "../src/utils/net.js";
|
|
|
|
describe("parseHostAllowlist", () => {
|
|
it("normalizes comma separated hosts", () => {
|
|
expect(parseHostAllowlist(" CDN.Example.com , *.OSS.example.com.,, ")).toEqual([
|
|
"cdn.example.com",
|
|
"*.oss.example.com",
|
|
]);
|
|
});
|
|
|
|
it("returns an empty list for empty input", () => {
|
|
expect(parseHostAllowlist("")).toEqual([]);
|
|
expect(parseHostAllowlist(undefined)).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("hostMatches", () => {
|
|
it("allows every host when the allowlist is empty", () => {
|
|
expect(hostMatches("anything.example.com", [])).toBe(true);
|
|
});
|
|
|
|
it("matches exact hosts case-insensitively", () => {
|
|
expect(hostMatches("CDN.example.com", ["cdn.example.com"])).toBe(true);
|
|
expect(hostMatches("other.example.com", ["cdn.example.com"])).toBe(false);
|
|
});
|
|
|
|
it("matches wildcard subdomains and the apex", () => {
|
|
expect(hostMatches("a.oss.example.com", ["*.oss.example.com"])).toBe(true);
|
|
expect(hostMatches("oss.example.com", ["*.oss.example.com"])).toBe(true);
|
|
expect(hostMatches("evil-oss.example.com", ["*.oss.example.com"])).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("isBlockedAddress", () => {
|
|
it.each([
|
|
"0.0.0.0",
|
|
"10.1.2.3",
|
|
"100.64.0.1",
|
|
"127.0.0.1",
|
|
"169.254.169.254",
|
|
"172.16.0.1",
|
|
"172.31.255.255",
|
|
"192.168.1.1",
|
|
"198.18.0.1",
|
|
"224.0.0.1",
|
|
"255.255.255.255",
|
|
])("blocks private or reserved IPv4 %s", (address) => {
|
|
expect(isBlockedAddress(address)).toBe(true);
|
|
});
|
|
|
|
it.each(["8.8.8.8", "1.1.1.1", "172.32.0.1", "93.184.216.34"])("allows public IPv4 %s", (address) => {
|
|
expect(isBlockedAddress(address)).toBe(false);
|
|
});
|
|
|
|
it.each(["::", "::1", "fe80::1", "fd00::1", "fc00::1", "ff02::1", "2001:db8::1"])(
|
|
"blocks private or reserved IPv6 %s",
|
|
(address) => {
|
|
expect(isBlockedAddress(address)).toBe(true);
|
|
},
|
|
);
|
|
|
|
it("blocks IPv4 mapped into IPv6", () => {
|
|
expect(isBlockedAddress("::ffff:127.0.0.1")).toBe(true);
|
|
expect(isBlockedAddress("::ffff:169.254.169.254")).toBe(true);
|
|
expect(isBlockedAddress("::ffff:8.8.8.8")).toBe(false);
|
|
});
|
|
|
|
it("blocks 6to4 addresses that embed a private IPv4", () => {
|
|
expect(isBlockedAddress("2002:7f00:1::")).toBe(true);
|
|
expect(isBlockedAddress("2002:0808:0808::")).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("isBlockedHostname", () => {
|
|
it.each([
|
|
"localhost",
|
|
"api.localhost",
|
|
"metadata.google.internal",
|
|
"db.internal",
|
|
"redis",
|
|
"127.0.0.1",
|
|
"169.254.169.254",
|
|
"[::1]",
|
|
])("blocks %s", (host) => {
|
|
expect(isBlockedHostname(host)).toBe(true);
|
|
});
|
|
|
|
it.each(["example.com", "cdn.example.com", "8.8.8.8"])("allows %s", (host) => {
|
|
expect(isBlockedHostname(host)).toBe(false);
|
|
});
|
|
});
|
|
|
|
describe("assertSafeUrl", () => {
|
|
it("rejects non-http protocols", async () => {
|
|
await expect(assertSafeUrl("ftp://example.com/a")).rejects.toThrow(/http/);
|
|
await expect(assertSafeUrl("file:///etc/passwd")).rejects.toThrow(/http/);
|
|
});
|
|
|
|
it("rejects URLs with credentials", async () => {
|
|
await expect(assertSafeUrl("https://user:pass@example.com/a")).rejects.toThrow(/账号|密码/);
|
|
});
|
|
|
|
it("rejects loopback and cloud metadata endpoints", async () => {
|
|
await expect(assertSafeUrl("http://127.0.0.1:3306")).rejects.toThrow(/禁止访问/);
|
|
await expect(assertSafeUrl("http://169.254.169.254/latest/meta-data")).rejects.toThrow(/禁止访问/);
|
|
await expect(assertSafeUrl("http://[::1]/")).rejects.toThrow(/禁止访问/);
|
|
});
|
|
|
|
it("rejects hosts outside the allowlist", async () => {
|
|
await expect(assertSafeUrl("https://evil.example.com/a", { allowedHosts: ["cdn.example.com"] })).rejects.toThrow(
|
|
/白名单/,
|
|
);
|
|
await expect(
|
|
assertSafeUrl("https://93.184.216.34/a", { allowedHosts: ["93.184.216.34"] }),
|
|
).resolves.toBeInstanceOf(URL);
|
|
});
|
|
|
|
it("accepts public IP literals", async () => {
|
|
await expect(assertSafeUrl("https://93.184.216.34/a")).resolves.toBeInstanceOf(URL);
|
|
});
|
|
});
|
|
|
|
describe("safeFetch", () => {
|
|
it("refuses to connect to a blocked host before any request is made", async () => {
|
|
await expect(safeFetch("http://127.0.0.1:9/")).rejects.toThrow(/禁止访问/);
|
|
});
|
|
});
|