Hiding a button is only UX (user experience). It is not security. The API endpoint behind the button still exists. Anyone can call it directly with curl or a modified client.
The server must make every authorization decision, on every request. Why? The attacker fully controls the client. When a regular user can call an admin function, OWASP calls this Broken Function Level Authorization.
Deny by default means the server refuses access unless a rule clearly allows it. In practice:
- New routes need authentication and a clear permission, unless someone marks them public on purpose.
- A missing or unknown role gives no access.
- If the authorization code throws an error, the request is denied. It is not let through. This is called failing closed.
Put the checks in one central place, such as middleware, guards or a policy layer. Then it's hard to forget a check on a new route.
- Client-side checks are only UX, not security.
- Attackers can call the API directly.
- The server must check authorization on every request.
- Deny unless a rule clearly allows access, and fail closed on errors.
- Keep authorization logic in one central place.
Read more