September 3, 2026
Broken Access Control (A01): Your Route Guard Won’t Stop an Attacker
You may have heard of the OWASP Top 10.

By Ayman Eldawy
2 min read
Today, we're looking at the risk that still holds the number one spot in the 2025 list: Broken Access Control (A01).
So what is it?
Broken Access Control happens when an application allows users to view data or perform actions outside their intended permissions.
Imagine an application where users can download their invoices through a URL like this:
/invoices/1001.pdf
A user changes url from1001 to 1002.
And suddenly, they can see someone else's invoice.
The problem isn't that the ID was easy to change. The real problem is that the server never checked whether the current user was allowed to access that invoice.
The Frontend Is Not a Security Boundary
One of the biggest mistakes a backend can make is trusting the frontend to protect sensitive actions.
Maybe the frontend:
- Hides the delete button.
- Disables a form field.
- Blocks unauthorized pages with a route guard.
That may improve the user experience.
But it doesn't secure the endpoint.
An attacker doesn't need your button or form. They can inspect the request and send it directly to the API.
If the server doesn't validate both the user's permissions and the incoming data, the frontend controls become irrelevant.
Common Forms of Broken Access Control
Insecure Direct Object References (IDOR)
Imagine this profile URL:
/profile/101
If changing it to /profile/102 exposes another user's private profile, the server is probably checking whether the user is authenticated, but not whether they are authorized to access that specific record.
Privilege Escalation
A regular user sends a request containing:
{
"role": "admin"
}{
"role": "admin"
}If the server trusts that value and updates the user, they have just promoted themselves to admin.
Convenient.
Probably not the feature you intended.
What Can the Frontend Do?
The frontend should still:
- Prevent users from navigating to pages they cannot use.
- Avoid rendering actions they are not allowed to perform.
- Build the interface around the permissions returned by the server.
But these controls are for UX and defense in depth.
A user controls their browser. They can modify the page, change JavaScript, and send requests without using your interface at all.
The real authorization decision must happen on the server.
How Do We Prevent It?
Validate authorization on every request.
The server should verify:
- Who is making the request?
- Are they allowed to perform this action?
- Are they allowed to access this specific resource?
Centralize authorization through middleware, guards, policies, or another reusable mechanism, but remember that record ownership and business rules may still require checks closer to the domain logic.
Follow deny by default.
Start with no access, then grant only the permissions each user actually needs. This is the principle of least privilege.
You can also use unpredictable identifiers such as UUIDs instead of sequential IDs. They make enumeration harder, but they are not an authorization mechanism.
If a user somehow obtains another UUID, the server must still reject the request.
So the mental model is simple:
Frontend permissions control what the user sees.
Server authorization controls what the user can actually do.
And this was post #8 in my Frontend Security series.