fix(auth): make diagnostics bounded and portable

This commit is contained in:
2026-08-17 12:19:19 +02:00
parent 7cfbee36fa
commit be1724890a
23 changed files with 1088 additions and 116 deletions
+53 -1
View File
@@ -254,17 +254,69 @@ describe("file-backed auth session store", () => {
symlinkSync(realRoot, linkedRoot);
const traversal = `${valid}/../${basename(valid)}`;
const absent = join(outer, "absent-auth");
const absentNested = join(outer, "absent-parent", "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(absent)).not.toThrow();
expect(existsSync(absent)).toBe(false);
for (const unsafe of [traversal, linkedRoot, absentNested, join(fileParent, "auth")]) {
expect(() => validateAuthSessionRoot(unsafe)).toThrow("auth_session_store_invalid");
}
expect(existsSync(join(outer, "absent-parent"))).toBe(false);
chmodSync(valid, 0o750);
expect(() => validateAuthSessionRoot(valid)).toThrow("auth_session_store_invalid");
});
test.skipIf(process.platform === "win32")("never follows a symlinked ancestor while creating a missing session root", async () => {
const outer = root();
const outside = root();
const linkedParent = join(outer, "linked-parent");
symlinkSync(outside, linkedParent);
const storageRoot = join(linkedParent, "auth");
await expectStoreInvalid(create(validStore(storageRoot)));
expect(existsSync(join(outside, "auth"))).toBe(false);
});
test.skipIf(process.platform === "win32")("rejects an uncreatable missing root without side effects in static and runtime paths", async () => {
const outer = root();
const lockedParent = join(outer, "locked-parent");
mkdirSync(lockedParent, { mode: 0o700 });
chmodSync(lockedParent, 0o500);
const storageRoot = join(lockedParent, "auth");
try {
expect(() => validateAuthSessionRoot(storageRoot)).toThrow("auth_session_store_invalid");
await expectStoreInvalid(create(validStore(storageRoot)));
expect(existsSync(storageRoot)).toBe(false);
} finally {
chmodSync(lockedParent, 0o700);
}
});
test.skipIf(process.platform === "win32")("detects an ancestor replacement before creating any session directory", async () => {
const outer = root();
const outside = root();
const parent = join(outer, "parent");
const movedParent = join(outer, "parent-original");
mkdirSync(parent, { mode: 0o700 });
chmodSync(parent, 0o700);
let replaced = false;
fsHooks.afterLstat = (observed) => {
if (observed !== parent) return false;
renameSync(parent, movedParent);
symlinkSync(outside, parent);
replaced = true;
return true;
};
await expectStoreInvalid(create(validStore(join(parent, "auth"))));
expect(replaced).toBe(true);
expect(existsSync(join(outside, "auth"))).toBe(false);
expect(existsSync(join(movedParent, "auth"))).toBe(false);
});
test.skipIf(process.platform === "win32")("rejects a session root owned by another identity", () => {
const storageRoot = root();
fsHooks.transformLstat = (observed, info) => {