Security overview
Defense in depth - security applied at every tier. No single point of failure.
Security layers
NextForge applies security at 5 distinct tiers:
- Input - Zod validation + XSS sanitization before any processing
- Business logic - rate limiting + auth re-verification in every action
- Database - injection prevention + parameterized queries
- Session - JWT strategy, HTTP-only cookies, auth re-check in server components
- Transport - security headers on every response via proxy.ts
Never rely on proxy.ts as your only auth gate
A CVE disclosed in 2025 demonstrated that Next.js middleware can be bypassed with a crafted x-middleware-subrequest header. proxy.ts redirects are a convenience layer - every server action and server component checks auth() independently.
Full security reference
Render this as a full-width table (w-full border-collapse):
| Layer | Implementation |
|---|---|
| Password hashing | bcrypt, cost factor 12 |
| OTP generation | crypto.randomInt (CSPRNG), 6-digit |
| OTP storage | SHA-256 hash stored, plaintext never persisted |
| OTP verification | crypto.timingSafeEqual - constant-time comparison |
| OTP expiry | 10 minutes, checked at query time with expiresAt > now |
| NoSQL injection | stripMongoOperators() strips $-prefixed and dot-notation keys |
| SQL injection | Supabase JS client uses parameterized queries internally |
| XSS | escapeHTML() applied to all user-supplied string inputs |
| Rate limiting | Upstash Redis sliding window - 5/min auth, 3/min OTP |
| Session | JWT strategy, AUTH_SECRET required in all environments |
| Route protection | proxy.ts redirects + independent auth() check in every action |
| Security headers | CSP, X-Frame-Options: DENY, X-Content-Type-Options: nosniff, HSTS |
| Email enumeration | Password reset and OTP resend always return the same response |
The middleware CVE
In early 2025, a critical CVE was disclosed affecting Next.js middleware. An attacker could bypass middleware-based authentication checks entirely by sending a crafted x-middleware-subrequest header - bypassing all redirect and auth logic in middleware.ts.
Next.js 16 addresses this by renaming middleware.ts to proxy.ts and changing the export function name from middleware to proxy, making bypass attempts less effective. However, the architectural lesson remains:
Middleware (proxy.ts) should only be a convenience redirect layer. Authentication must be re-verified inside server actions and server components using auth(). NextForge is designed this way throughout - proxy.ts handles redirects, every action checks its own session.