What is broken access control?
Access control means enforcing rules about who can see or change what. Broken access control is when those rules are missing, incomplete, or bypassable. A user can view another user's profile. A member can hit admin endpoints. A customer can modify someone else's order by changing an ID in the URL.
It's been the #1 vulnerability category in the OWASP Top 10 since 2021. Not because it's complicated to fix — but because it's easy to forget. Every endpoint needs its own check. Miss one, and the whole boundary breaks.
What it looks like in code
Here's a typical API route generated by an AI tool. It fetches a user by the id parameter from the URL — but it never checks whether the person making the request is allowed to see that data.
// app/api/users/[id]/route.ts
export async function GET(req, { params }) {
const { id } = params;
// Fetches ANY user by ID — no ownership check
const user = await db.query(
'SELECT * FROM users WHERE id = $1',
[id]
);
return Response.json(user);
}// app/api/users/[id]/route.ts
export async function GET(req, { params }) {
const session = await getSession(req);
const { id } = params;
// Only return data if the requesting user owns it
const user = await db.query(
'SELECT * FROM users WHERE id = $1 AND user_id = $2',
[id, session.user.id]
);
if (!user) return new Response(null, { status: 404 });
return Response.json(user);
}The fix adds two lines: get the session and filter by the authenticated user's ID. That's it. But AI tools almost never generate that second WHERE clause unless you explicitly ask for it.
Why AI tools generate this
Access control bugs aren't accidents. They're a predictable result of how AI code generation works.
- They optimize for "it works." AI generates code that fulfills the prompt — fetch a user, display a profile, list orders. The happy path works. But there’s no concept of "this user shouldn’t see that data." Access control is a constraint the prompt almost never specifies.
- Authorization is contextual. Unlike input validation (which has clear patterns), access control depends on your app’s business logic. Who can see what? Which roles exist? AI tools don’t have that context, so they skip it entirely.
- Defaults are wide open. Supabase tables ship with RLS disabled. Next.js API routes have no built-in auth middleware. Express endpoints are public by default. AI tools use these defaults and move on.
Common patterns
Sequential ID enumeration
User IDs like /api/users/1, /api/users/2, /api/users/3. Change the number, get someone else’s data. AI almost always uses auto-incrementing IDs without ownership checks.
Missing RLS on Supabase tables
Row Level Security is disabled by default. AI tools create tables and insert data without ever running ALTER TABLE ... ENABLE ROW LEVEL SECURITY. Every row is readable by every user.
Privilege escalation via role field
Registration endpoints that accept a role field in the request body. Send {"role": "admin"} during signup and grant yourself full access. Mass assignment at its worst.
Unprotected admin endpoints
Admin routes like /api/admin/users or /api/settings that check if you’re logged in but never check if you’re actually an admin. Any authenticated user can access them.
How Flowpatrol detects it
Flowpatrol doesn't just check for missing auth headers. It tests actual access boundaries the way a real attacker would.
- 1Creates multiple test accounts. Flowpatrol registers or logs in as two separate users with different roles and permissions.
- 2Maps every endpoint. It crawls your app, captures every API call, and builds a map of your entire data surface.
- 3Cross-tests access. It takes User A’s session and tries to access User B’s data. Every endpoint, every ID, every role boundary.
- 4Flags what leaks. If User A can read, modify, or delete User B’s data, you get a finding with the exact endpoint, payload, and response.
No guesswork. No theoretical warnings. You get proof — specific endpoints where access control is broken, with the exact requests and responses.
Check your app for access control flaws.
Paste your URL. Flowpatrol tests every endpoint with multiple users and tells you exactly what leaks.
Try it free