-
Notifications
You must be signed in to change notification settings - Fork 0
[Security] Auth middleware marks all /api/* paths as public routes #43
Description
Summary
src/lib/supabase/middleware.ts includes /api in the PUBLIC_ROUTES array. The isPublicRoute() function matches any path starting with /api/, effectively making ALL API endpoints publicly accessible at the middleware level.
Location
// src/lib/supabase/middleware.ts
const PUBLIC_ROUTES = [
"/",
"/login",
"/register",
// ...
"/api", // This makes ALL /api/* routes "public"
// ...
];
function isPublicRoute(pathname: string): boolean {
return PUBLIC_ROUTES.some(
(route) => pathname === route || pathname.startsWith(route + "/")
);
}Impact
The middleware skips Supabase session refresh for ALL API routes. While each API route handler does its own supabase.auth.getUser() check, the middleware would normally:
- Refresh expired session tokens automatically
- Redirect unauthenticated users
By marking /api as public, the middleware provides no defense-in-depth for API routes. If any API handler forgets the auth check, it becomes an unauthenticated endpoint.
This is particularly concerning because:
/api/webhooks/*are intentionally public (receives from Twilio/Telnyx)- But
/api/messages/*,/api/contacts/*,/api/campaigns/*should NOT be public at middleware level - The intent was likely to only expose
/api/healthand/api/webhooks/*as public
Suggested Fix
Replace the broad /api entry with specific public API paths:
const PUBLIC_ROUTES = [
// ...
"/api/health",
"/api/webhooks",
"/api/waitlist",
// NOT "/api" — too broad
];Severity
Medium — Defense-in-depth gap. Individual route handlers still check auth, but one missing check = full vulnerability.