fix(auth): make diagnostics match runtime safety
This commit is contained in:
@@ -18,7 +18,7 @@ import {
|
||||
writeFileSync,
|
||||
} from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { basename, join } from "node:path";
|
||||
import { afterEach, describe, expect, test, vi } from "vitest";
|
||||
|
||||
const fsHooks = vi.hoisted(() => ({
|
||||
@@ -66,6 +66,7 @@ vi.mock("node:fs", async (importOriginal) => {
|
||||
import {
|
||||
createFileAuthSessionStore,
|
||||
deriveCsrfToken,
|
||||
validateAuthSessionRoot,
|
||||
type AuthSessionStore,
|
||||
type FileAuthSessionStoreOptions,
|
||||
type SessionCreateInput,
|
||||
@@ -241,6 +242,41 @@ async function isolatedOidcCreator(storageRoot: string, attempts: number): Promi
|
||||
}
|
||||
|
||||
describe("file-backed auth session store", () => {
|
||||
test.skipIf(process.platform === "win32")("exports its side-effect-free canonical session-root validator", () => {
|
||||
const valid = root();
|
||||
expect(() => validateAuthSessionRoot(valid)).not.toThrow();
|
||||
|
||||
const outer = root();
|
||||
const realRoot = join(outer, "real-auth");
|
||||
mkdirSync(realRoot, { mode: 0o700 });
|
||||
chmodSync(realRoot, 0o700);
|
||||
const linkedRoot = join(outer, "linked-auth");
|
||||
symlinkSync(realRoot, linkedRoot);
|
||||
const traversal = `${valid}/../${basename(valid)}`;
|
||||
const absent = join(outer, "absent-auth");
|
||||
const fileParent = join(outer, "not-a-directory");
|
||||
writeFileSync(fileParent, "blocked", { mode: 0o600 });
|
||||
|
||||
for (const unsafe of [traversal, linkedRoot, absent, join(fileParent, "auth")]) {
|
||||
expect(() => validateAuthSessionRoot(unsafe)).toThrow("auth_session_store_invalid");
|
||||
}
|
||||
|
||||
chmodSync(valid, 0o750);
|
||||
expect(() => validateAuthSessionRoot(valid)).toThrow("auth_session_store_invalid");
|
||||
});
|
||||
|
||||
test.skipIf(process.platform === "win32")("rejects a session root owned by another identity", () => {
|
||||
const storageRoot = root();
|
||||
fsHooks.transformLstat = (observed, info) => {
|
||||
if (observed !== storageRoot) return info;
|
||||
const foreign = Object.create(info) as import("node:fs").Stats;
|
||||
Object.defineProperty(foreign, "uid", { value: info.uid + 1 });
|
||||
return foreign;
|
||||
};
|
||||
|
||||
expect(() => validateAuthSessionRoot(storageRoot)).toThrow("auth_session_store_invalid");
|
||||
});
|
||||
|
||||
test("fails closed and revokes a session when constructed without validity dependencies", async () => {
|
||||
const storageRoot = root();
|
||||
const store = createFileAuthSessionStore(storageRoot);
|
||||
|
||||
Reference in New Issue
Block a user