An unauthenticated API route that reads or writes user data is a direct broken-access-control vulnerability — any visitor with the URL can enumerate profiles, export other tenants' records, or mutate state belonging to accounts they don't own. AI coding tools routinely produce this failure mode because they scaffold route handlers from example snippets that skip the session check, and because request-body validation visually looks like "protection" even though it enforces shape, not identity. The same pattern also catches webhook endpoints that accept arbitrary POST payloads without verifying the provider signature, which lets anyone forge subscription upgrades, payment confirmations, or delivery events. This is the single most common critical finding in post-incident reviews of vibe-coded apps.
High because an unauthenticated data route is directly exploitable by any visitor with the URL — no credentials, tooling, or chained vulnerabilities required — and typically exposes multi-tenant data in bulk.
Add an auth check at the top of each protected handler:
const session = await getSession()
if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })
Deeper remediation guidance and cross-reference coverage for this check lives in the data-protection Pro audit — run that after applying this fix for a more exhaustive pass on the same topic.
project-snapshot.data-exposure.api-routes-have-authhighapp/api/**/route.ts, pages/api/**, Express/Fastify route registrations). Classify each as: (a) intentionally public (auth, signup, login, public read endpoints, webhooks with signature verification, health checks), (b) protected and has a session/API-key check, (c) neither — appears to access user data without authentication. Count each."Found N API routes: P public, Q protected (auth check confirmed), 0 unprotected.""3 API routes appear to access user data without auth: app/api/users/[id]/route.ts (GET returns full profile), ...".data-protection audit.const session = await getSession()
if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })