VibeCheck-AI

The admin route nobody checks

Security basicsJun 21, 20264 min read

Signed in is not the same as allowed. The most common high-severity finding we write rules for is an admin page that only checks whether you have an account.

There are two questions an app has to ask about anyone making a request. Who are you, and are you allowed to do this? The first is authentication. The second is authorisation. Generated code is good at the first and frequently skips the second entirely.

The result is an admin page that checks you have an account, and never checks whose account it is. Every signed-up user is an administrator. Nothing about the code looks wrong, because the check that is there is written correctly — it is just answering the wrong question.

Why it is so easy to miss

The page works when you test it, because you are the administrator. It works when a normal user tests it, because a normal user does not type `/admin` into the address bar. It only fails when somebody guesses a URL, and guessing `/admin` is not much of a guess.

Framework middleware makes this worse in a specific way. A matcher pattern that protects `/dashboard` looks like it protects everything that matters, and then a route gets added at `/admin` or `/api/admin`, outside the pattern. The protection is real, correctly written, and pointed somewhere else.

What to check

For every page and every API route that can change something or read someone else's data, find the line that checks the requester's role — not their session, their role. If you cannot find that line, it is not there.

Check it on the server, in the route handler or the server component. A check that only hides a button in the interface hides a button. The route underneath it still answers.

What we report

Route protection is part of the second pass, using our own rules, and a missing role check on an admin surface is a high-severity finding. The report names the route, says who can currently reach it, and describes what they could do when they get there — because “add an authorisation check” is advice, and “anyone with an account can currently delete any user” is a reason to stop what you are doing.

Stop reading, start scanning.

Free needs no card. One repository, read-only, two scans a day.