You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Five independently-discovered backend security gaps that together close the most critical backend attack surface: missing config should deny, not allow; headers leaked to upstream should be explicit; billing should never be zero on success; admin rendering should escape untrusted data; and cookie-authed mutations should verify same-origin.
To do
1. Fail closed on missing security config (was #25)
Goal
Harden backend security across five fronts: fail-closed configs, proxy header hygiene, billing accuracy, admin XSS prevention, and CSRF protection.
Merged from
Why this matters
Five independently-discovered backend security gaps that together close the most critical backend attack surface: missing config should deny, not allow; headers leaked to upstream should be explicit; billing should never be zero on success; admin rendering should escape untrusted data; and cookie-authed mutations should verify same-origin.
To do
1. Fail closed on missing security config (was #25)
Files:
backend/src/lib/cron-auth.ts,backend/src/lib/ratelimit.tsisProduction()helper (checksVERCEL_ENV || NODE_ENV === 'production')CRON_SECRETunset in prod → deny (fail closed)ratelimit_misconfiguredlog (fail closed)cron-auth.test.ts,ratelimit.test.ts2. Proxy header allowlist (was #26)
Files:
backend/src/lib/proxy.tsbuildForwardHeaderswith explicitFORWARD_ALLOWLISTcontent-type,accept,accept-encoding,user-agent, provider-specific beta headersauthorization,cookie,x-api-key,x-forwarded-*,cf-*,vercel-*, internal headersproxy.test.ts3. Billing fail-closed on missing usage (was #27)
Files:
backend/src/lib/proxy.tsresolveBillableTokens()— on 2xx with zero output tokens, fall back to estimated input + minimum outputestimatedInputTokensthroughBillContextusage_missing_on_successas error for alertingproxy-billing.test.ts4. Admin dashboard XSS (was #28)
Files:
backend/src/pages/admin.astroesc()HTML-escape helper to inline scriptesc(): model names, providers, emails, audit metadatapnpm -C backend buildexits 05. CSRF same-origin protection (was #29)
Files:
backend/src/lib/csrf.ts, multiple mutation routesrequireSameOrigin(request)— returns null (ok) or 403 Responseexport const GET = POSTfrom signout (GET signout is CSRF-able)/api/v1/**) out of scopecsrf.test.tsVerified together
mise exec -- pnpm -C backend test— all passmise exec -- pnpm test— exit 0mise exec -- pnpm -C backend build— exit 0