mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 13:41:24 +00:00
test: optimize gateway infra memory and security coverage
This commit is contained in:
@@ -15,37 +15,22 @@ function okResponse(body = "ok"): Response {
|
||||
describe("fetchWithSsrFGuard hardening", () => {
|
||||
type LookupFn = NonNullable<Parameters<typeof fetchWithSsrFGuard>[0]["lookupFn"]>;
|
||||
|
||||
it("blocks private IP literal URLs before fetch", async () => {
|
||||
const fetchImpl = vi.fn();
|
||||
await expect(
|
||||
fetchWithSsrFGuard({
|
||||
url: "http://127.0.0.1:8080/internal",
|
||||
fetchImpl,
|
||||
}),
|
||||
).rejects.toThrow(/private|internal|blocked/i);
|
||||
expect(fetchImpl).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks legacy loopback literal URLs before fetch", async () => {
|
||||
const fetchImpl = vi.fn();
|
||||
await expect(
|
||||
fetchWithSsrFGuard({
|
||||
url: "http://0177.0.0.1:8080/internal",
|
||||
fetchImpl,
|
||||
}),
|
||||
).rejects.toThrow(/private|internal|blocked/i);
|
||||
expect(fetchImpl).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("blocks unsupported packed-hex loopback literal URLs before fetch", async () => {
|
||||
const fetchImpl = vi.fn();
|
||||
await expect(
|
||||
fetchWithSsrFGuard({
|
||||
url: "http://0x7f000001/internal",
|
||||
fetchImpl,
|
||||
}),
|
||||
).rejects.toThrow(/private|internal|blocked/i);
|
||||
expect(fetchImpl).not.toHaveBeenCalled();
|
||||
it("blocks private and legacy loopback literals before fetch", async () => {
|
||||
const blockedUrls = [
|
||||
"http://127.0.0.1:8080/internal",
|
||||
"http://0177.0.0.1:8080/internal",
|
||||
"http://0x7f000001/internal",
|
||||
];
|
||||
for (const url of blockedUrls) {
|
||||
const fetchImpl = vi.fn();
|
||||
await expect(
|
||||
fetchWithSsrFGuard({
|
||||
url,
|
||||
fetchImpl,
|
||||
}),
|
||||
).rejects.toThrow(/private|internal|blocked/i);
|
||||
expect(fetchImpl).not.toHaveBeenCalled();
|
||||
}
|
||||
});
|
||||
|
||||
it("blocks redirect chains that hop to private hosts", async () => {
|
||||
|
||||
@@ -59,27 +59,23 @@ const unsupportedLegacyIpv4Cases = [
|
||||
const nonIpHostnameCases = ["example.com", "abc.123.example", "1password.com", "0x.example.com"];
|
||||
|
||||
describe("ssrf ip classification", () => {
|
||||
it.each(privateIpCases)("classifies %s as private", (address) => {
|
||||
expect(isPrivateIpAddress(address)).toBe(true);
|
||||
});
|
||||
|
||||
it.each(publicIpCases)("classifies %s as public", (address) => {
|
||||
expect(isPrivateIpAddress(address)).toBe(false);
|
||||
});
|
||||
|
||||
it.each(malformedIpv6Cases)("fails closed for malformed IPv6 %s", (address) => {
|
||||
expect(isPrivateIpAddress(address)).toBe(true);
|
||||
});
|
||||
|
||||
it.each(unsupportedLegacyIpv4Cases)(
|
||||
"fails closed for unsupported legacy IPv4 literal %s",
|
||||
(address) => {
|
||||
it("classifies blocked ip literals as private", () => {
|
||||
const blockedCases = [...privateIpCases, ...malformedIpv6Cases, ...unsupportedLegacyIpv4Cases];
|
||||
for (const address of blockedCases) {
|
||||
expect(isPrivateIpAddress(address)).toBe(true);
|
||||
},
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
it.each(nonIpHostnameCases)("does not treat hostname %s as an IP literal", (hostname) => {
|
||||
expect(isPrivateIpAddress(hostname)).toBe(false);
|
||||
it("classifies public ip literals as non-private", () => {
|
||||
for (const address of publicIpCases) {
|
||||
expect(isPrivateIpAddress(address)).toBe(false);
|
||||
}
|
||||
});
|
||||
|
||||
it("does not treat hostnames as ip literals", () => {
|
||||
for (const hostname of nonIpHostnameCases) {
|
||||
expect(isPrivateIpAddress(hostname)).toBe(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user