Heimdall Scan logo, AI security scanner for vibe coders
Heimdall ScanOpen Beta
CriticalAccess Control

Admin pages and APIs that don't check for an actual admin

Admin privilege escalation happens when an admin-only page or API route checks that a user is logged in, but never confirms they're actually an admin. Any signed-up user who finds the URL or the API endpoint gets full admin access.

#What goes wrong

AI editors are good at wiring up 'if user is logged in, show this page' but often stop there, because the admin dashboard was built and tested by the one person who happens to also be the admin. The missing role check is invisible until a regular user stumbles onto /admin.

#Why it matters

This is one of the easiest bugs to exploit and one of the most damaging: an attacker who finds an unprotected admin API can delete other users, change plans, issue refunds, or read every record in your database, all without needing to guess a password.

#How Heimdall checks for this

Heimdall reads your admin pages and admin API routes and looks for a server-side role check, like user.role === 'admin' or an equivalent database lookup, that runs before any admin action. A session check alone doesn't count.

#How to fix it

Add a server-side check right after authentication that reads the user's role from your database, not from a client-supplied field, and rejects the request with a 403 if it isn't 'admin'. Do this in every admin route, or centralize it in middleware that covers the admin path.

Frequently asked questions

Isn't hiding the admin link from the UI enough?

Can I trust a role field sent from the client?

I have a database rule that checks role. Do I still need a route-level check?

Run this check on your own repo

Heimdall scans your GitHub repo for this and 29 other issues in under a minute.