Security through obscurity is not security at all.
Many applications have administrative features (e.g., deleting users, viewing all orders). Often, developers hide the links to these features in the UI if the user is not an Admin. However, if they forget to enforce the role check on the backend API itself, a regular user can simply guess the URL (e.g., `/api/admin/delete_user`) and execute the command directly.
Every privileged API endpoint must explicitly check the role of the authenticated user. Do not assume that because the user reached the endpoint, they were authorized to do so by the frontend.
# VULNERABLE: Only checks if logged in
@app.route("/api/admin/delete_user", methods=["POST"])
@login_required # DANGER: Any logged in user can pass this!
def delete_user():
db.delete_user(request.json['user_id'])
return "User deleted"
# SECURE: Checks Role (RBAC)
@app.route("/api/admin/delete_user", methods=["POST"])
@login_required
@requires_role("ADMIN") # Explicitly verifies admin status
def delete_user():
db.delete_user(request.json['user_id'])
return "User deleted"
An e-commerce site has a frontend React app. If the user's `role` is `user`, it shows the shopping cart. If the `role` is `admin`, it shows a dashboard with a button to `GET /api/reports/financials`. A malicious standard user downloads an API scanning tool (like Postman or Burp Suite), guesses the URL `/api/reports/financials`, and sends a request. Because the Node.js backend only checked if the user had a valid session (not their role), the backend returns the company's entire financial history.
Why is hiding a button in the frontend HTML insufficient for securing administrative functionality?