@factory/security
TASK-0134 security audit suites (OWASP ASVS L2 baseline). Runs as a CI stage
between build and E2E (.github/workflows/ci.yml → security job) — several
suites need the live dev stack (auth paths, rate limits, upload abuse); the
rest are offline config/lint checks.
The 10 suites
| Suite | Checks |
|---|---|
deps.test.ts |
Dependency + license audit (vulnerable / license-blocked packages fail) |
gitleaks-config.test.ts |
gitleaks.toml is valid and covers the repo's secret classes |
auth-paths.test.ts |
Auth-path review: JWT alg pinning, refresh-reuse detection, session fixation, cookie flags, CSRF route walk (live stack) |
permission-fuzz.test.ts |
Permission engine fuzzing — fast-check inputs vs the brute-force oracle (oracle.ts) |
headers.test.ts |
CORS / CSRF / CSP response-header crawler (live stack) |
upload-abuse.test.ts |
File-upload abuse: content-type spoofing, size caps, path traversal (live stack) |
formula-fuzz.test.ts |
Formula engine fuzz — 100k-op / 50 ms guard checks against the safe AST evaluator |
rate-limits.test.ts |
Rate-limit verification per tier (live stack) |
images.test.ts |
Build-image artifact secret scans |
audit-report.test.ts |
Cross-checks the generated audit report for completeness |
Shared helpers live in helpers/ (app.ts — stack bootstrap + request
harness).
Running
pnpm --dir tests/security test # vitest run (all 10 suites)
pnpm --dir tests/security typecheck # tsc --noEmit
A new finding is never "fixed" by editing a suite's assertions — open a task, land the code or config fix, and update the suite only to lock in the new expected behavior.