55 lines
2.4 KiB
TypeScript
55 lines
2.4 KiB
TypeScript
import { afterAll, beforeAll, expect, test } from "vitest";
|
|
import { createLocalAuthFixture, type LocalAuthFixture, localPublicUrl } from "./auth-test-fixtures.js";
|
|
|
|
let fixture: LocalAuthFixture;
|
|
|
|
beforeAll(async () => {
|
|
fixture = await createLocalAuthFixture();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await fixture.close();
|
|
});
|
|
|
|
test("credentialed CORS permits only the current configured public origin", async () => {
|
|
const allowedPreflight = await fixture.app.inject({
|
|
method: "OPTIONS", url: "/me",
|
|
headers: { origin: localPublicUrl, "access-control-request-method": "GET" },
|
|
});
|
|
expect(allowedPreflight.statusCode).toBe(204);
|
|
expect(allowedPreflight.headers["access-control-allow-origin"]).toBe(localPublicUrl);
|
|
expect(allowedPreflight.headers["access-control-allow-credentials"]).toBe("true");
|
|
|
|
const canonicalPreflight = await fixture.app.inject({
|
|
method: "OPTIONS", url: "/me",
|
|
headers: { origin: "HTTP://127.0.0.1:8787", "access-control-request-method": "GET" },
|
|
});
|
|
expect(canonicalPreflight.statusCode).toBe(204);
|
|
expect(canonicalPreflight.headers["access-control-allow-origin"]).toBe(localPublicUrl);
|
|
|
|
const attackerPreflight = await fixture.app.inject({
|
|
method: "OPTIONS", url: "/me",
|
|
headers: { origin: "https://attacker.example.test", "access-control-request-method": "GET" },
|
|
});
|
|
expect(attackerPreflight.headers["access-control-allow-origin"]).toBeUndefined();
|
|
expect(attackerPreflight.headers["access-control-allow-credentials"]).toBeUndefined();
|
|
|
|
const allowed = await fixture.app.inject({
|
|
method: "GET", url: "/me", headers: { cookie: fixture.cookie, origin: localPublicUrl },
|
|
});
|
|
expect(allowed.statusCode).toBe(200);
|
|
expect(allowed.headers["access-control-allow-origin"]).toBe(localPublicUrl);
|
|
expect(allowed.headers["access-control-allow-credentials"]).toBe("true");
|
|
|
|
const attacker = await fixture.app.inject({
|
|
method: "GET", url: "/me", headers: { cookie: fixture.cookie, origin: "https://attacker.example.test" },
|
|
});
|
|
expect(attacker.statusCode).toBe(200);
|
|
expect(attacker.headers["access-control-allow-origin"]).toBeUndefined();
|
|
expect(attacker.headers["access-control-allow-credentials"]).toBeUndefined();
|
|
|
|
const nonBrowser = await fixture.app.inject({ method: "GET", url: "/me", headers: { cookie: fixture.cookie } });
|
|
expect(nonBrowser.statusCode).toBe(200);
|
|
expect(nonBrowser.headers["access-control-allow-origin"]).toBeUndefined();
|
|
});
|