Logged-in routes are where many apps hide the real problems.
The public homepage can look polished while the dashboard has missing labels, broken mobile layouts, exposed data, weak authorization or admin links that only disappear because the UI hides them.
If your app has accounts, dashboards, payments, settings, teams or admin pages, you need to test authenticated routes before launch.
Authentication is not authorization
Authentication asks:
Who is this user?
Authorization asks:
What is this user allowed to do?
An authenticated user should not automatically access every logged-in route.
Common boundaries include:
- normal user vs admin
- owner vs team member
- paid vs unpaid account
- tenant A vs tenant B
- public report vs private report
- support agent vs customer
AI-generated apps often check these boundaries in the UI but forget to enforce them on the server.
Search for sensitive routes
Run:
rg "admin|dashboard|settings|billing|account|team" app
rg "isAdmin|role|permission|session|auth" app lib components
Then ask:
Review authenticated and admin routes in this app.
For each route, identify:
- who should access it
- how access is enforced
- whether enforcement happens server-side or only in the UI
- what data it loads
- what actions it allows
- what negative tests we should run before launch
UI hiding is not security
This is unsafe:
Hide the admin button if user.isAdmin is false.
That is good UX, but it is not enough.
The admin page and admin API routes must also reject non-admin users.
Use this prompt:
Find any place where access control is only enforced by hiding UI.
For each case, add or recommend server-side authorization checks on the page, route handler, server action or database query.
Test logged-out access
Open private browsing or sign out.
Try direct URLs:
/dashboard/settings/account/billing/admin- private report URLs
- API routes used by the dashboard
Expected behaviour:
- redirect to sign in
- return 401
- return 404 for resources that should not reveal existence
Unexpected behaviour:
- dashboard shell loads with data
- API returns private JSON
- admin route renders then hides content
- error reveals implementation details
Test wrong-user access
Create two test users.
Try to access User B's resources as User A.
Use this prompt:
Create a wrong-user access test plan.
Assume we have User A and User B.
List URLs, API calls and actions where User A might try to access User B's data.
For each, define the expected safe response.
This catches IDOR issues: insecure direct object references.
If changing an ID in a URL exposes another user's data, launch should stop.
Test admin boundaries
Admin areas deserve extra care.
Check:
- admin routes require admin role server-side
- admin API routes reject normal users
- admin data is not bundled into normal pages
- role changes cannot be performed by normal users
- support tools do not expose secrets
- audit logs do not leak private payloads
Ask:
Review admin functionality as an attacker with a normal user account.
Find any way to access admin pages, admin API routes, elevated actions, user lists, payment data, support data, logs or internal tools.
Authenticated PageLens scans
Some issues only exist behind login.
Public scans catch public launch problems. Authenticated scans let PageLens inspect logged-in surfaces using safe test credentials.
Use a test account with:
- realistic data
- no real customer secrets
- limited permissions
- stable credentials
- permission boundaries you understand
Do not use a real admin account for routine scanning unless you are deliberately testing admin surfaces and understand the exposure.
What good looks like
Before launch:
- logged-out users cannot access private pages
- normal users cannot access admin pages
- tenants cannot access each other's data
- paid features check entitlement server-side
- private API routes reject unauthorized requests
- direct URL access behaves safely
- PageLens has scanned the important authenticated surfaces
The test is not "can I use my own dashboard?"
The test is "can someone else use my dashboard in a way I did not intend?"