chore: ran security check for OWASP top 10
Some checks failed
Deploy / deploy (push) Has been cancelled

This commit is contained in:
2026-03-01 20:44:55 -06:00
parent 023587c48c
commit 1645896e54
20 changed files with 1916 additions and 168 deletions

View File

@@ -0,0 +1,77 @@
import { afterAll, beforeAll, describe, expect, it } from "vitest";
import request from "supertest";
import type { FastifyInstance } from "fastify";
import { buildApp } from "../src/server";
let authApp: FastifyInstance;
let csrfApp: FastifyInstance;
const capturedEvents: Array<Record<string, unknown>> = [];
function attachSecurityEventCapture(app: FastifyInstance) {
const logger = app.log as any;
const originalChild = logger.child.bind(logger);
logger.child = (...args: any[]) => {
const child = originalChild(...args);
const originalWarn = child.warn.bind(child);
child.warn = (obj: unknown, ...rest: unknown[]) => {
if (obj && typeof obj === "object") {
const payload = obj as Record<string, unknown>;
if (typeof payload.securityEvent === "string") capturedEvents.push(payload);
}
return originalWarn(obj, ...rest);
};
return child;
};
}
beforeAll(async () => {
authApp = await buildApp({ AUTH_DISABLED: false, SEED_DEFAULT_BUDGET: false });
await authApp.ready();
(authApp as any).ensureUser = async () => undefined;
attachSecurityEventCapture(authApp);
csrfApp = await buildApp({ AUTH_DISABLED: true, SEED_DEFAULT_BUDGET: false });
await csrfApp.ready();
(csrfApp as any).ensureUser = async () => undefined;
attachSecurityEventCapture(csrfApp);
});
afterAll(async () => {
if (authApp) await authApp.close();
if (csrfApp) await csrfApp.close();
});
describe("A09 Security Logging and Monitoring Failures", () => {
it("emits structured security log for unauthenticated protected-route access", async () => {
capturedEvents.length = 0;
const res = await request(authApp.server).get("/dashboard");
expect(res.status).toBe(401);
const event = capturedEvents.find((payload) => {
return payload.securityEvent === "auth.unauthenticated_request";
});
expect(event).toBeTruthy();
expect(event?.outcome).toBe("failure");
expect(typeof event?.requestId).toBe("string");
expect(typeof event?.ip).toBe("string");
});
it("emits structured security log for csrf validation failures", async () => {
capturedEvents.length = 0;
const res = await request(csrfApp.server)
.post("/me")
.set("x-user-id", `csrf-user-${Date.now()}`)
.send({ displayName: "NoCsrf" });
expect(res.status).toBe(403);
expect(res.body.code).toBe("CSRF");
const event = capturedEvents.find((payload) => payload.securityEvent === "csrf.validation");
expect(event).toBeTruthy();
expect(event?.outcome).toBe("failure");
expect(typeof event?.requestId).toBe("string");
expect(typeof event?.ip).toBe("string");
});
});