High
Admin pages hidden, not protected
The admin button is hidden in the UI, but the admin API answers anyone.
What it is
Admin features are hidden by not showing a button, while the page or API behind it has no server-side role check. Anyone who finds the URL can use it.
Why fast-built apps get it
It's natural to “protect” admin with if (user.isAdmin) in a component. AI tools copy that pattern, and admin URLs leak through JavaScript bundles and sitemaps.
Before and after the cure
"use client";
export default function Admin() {
const { user } = useUser();
if (!user?.isAdmin) return null; // only hides the UI
return <UsersTable />; // which calls /api/admin/users freely
}export async function GET(req: Request) {
const user = await requireUser(req);
if (user.role !== "admin") {
return new Response("Forbidden", { status: 403 });
}
return Response.json(await db.user.findMany());
}What it can cost you
- Users granting themselves free plans or credits
- Bulk exports of all customers
- Changes to other users' accounts
Check your own app
- Search your JS bundle for “/admin” and try those URLs logged in as a normal user
- Check every admin API route checks the role on the server
- Look for role or isAdmin values read from the client
The cure
- Check roles on the server for every admin page and API
- Read roles from your database or signed session, never from the client
- Log every admin action with who did it
Other high loopholes
High
No rate limits
Login, OTP and AI endpoints that can be hit a million times.
See the cureHigh
AI features that can be talked into anything
Users trick your AI into leaking data, prompts or running tools it shouldn't.
See the cureHigh
Outdated packages with known holes
Libraries in your lockfile with public, exploitable vulnerabilities.
See the cureDoes your app have this one?
We'll check this and every other loophole on your app, then give you the cure.
Talk to us on WhatsApp