Skip to main content

Web auth hardening assessment

Assessment of cookie-based web auth before adding token-based native auth. Gate: Native login (tracked in internal working notes; not published on the docs site).

Summary

AreaRecommendation
CSRFNo change required. SameSite=Lax is sufficient.
Secure flagsNo change required.
Session cleanupSchedule required. Job exists; document production scheduling.

Current state

AreaImplementationLocation
Cookiesid httpOnly, path /, SameSite lax, Secure = NODE_ENV === "production"services/api/src/routes/auth.ts
CSRFNone. Relies on SameSite=Lax
Session cleanupJob exists (job:session-cleanup), manual run onlyservices/api/src/jobs/sessionCleanup.ts
Session TTL14 days; expired sessions rejected on request and deleted best-effortservices/api/src/plugins/sessionAuth.ts, auth.ts
Web requestscredentials: "same-origin" on all API fetchesapps/web/app/_lib/apiClient.ts
ArchitectureWeb and API same-origin via nginx proxy (/ and /api/)infra/nginx/dev.conf

Recommendations and rationale

CSRF

Risk: Cross-site request forgery — attacker tricks user into submitting a request that uses the victim's session.

Mitigation in place: SameSite=Lax — cookie is not sent on cross-site POST/PUT/DELETE/PATCH. Same-origin API.

Residual risk: Low. SameSite=Lax is effective for most CSRF scenarios.

Recommendation: No change required for gate. Optional future: CSRF tokens for defense-in-depth.

Secure flags

Current: secure: process.env.NODE_ENV === "production".

Recommendation: No change required. Cookie is set with Secure when NODE_ENV=production; browser sends it only over HTTPS.

Session cleanup

Current: Job exists; must be run manually. Expired sessions accumulate without scheduling.

Recommendation: Schedule the job daily in production. See docs/AUTH-STRATEGY.md for instructions.


Gate complete for native auth.