Skip to content

[Security] Auth middleware marks all /api/* paths as public routes #43

@eltociear

Description

@eltociear

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:

  1. Refresh expired session tokens automatically
  2. 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/health and /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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions