Build1 publisher2 min readPublished
A normal user reached an RBAC app's admin functions through a route the server never checked
A reviewer with eight years' experience reached a restaurant app's admin functions from his non-admin session because its endpoints never checked his role. The app was built with RBAC middleware, but the role check ran only in the browser.
The Engineer · Build desk

What happened
- Authentication worked throughout, with users signed in and sessions holding, yet the admin button hidden for the reviewer's role pointed at a route the server still answered.
- The choice to hide that button lived in JavaScript shipped to every visitor, so the reviewer found the admin route by reading the app's own client code in the browser inspector.
- He reached administrator functionality without the admin password and without touching the server, the database, or anyone's credentials.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- constraint A rule enforced only in the browser constrains nothing on the server; removing or hiding the button leaves the route returning exactly what it did before.
- exposure Any account that can log in is a candidate: the requests came from the interface itself, so no brute force, stolen session, or password was needed to replay them.
- decision Whatever RBAC framework an app ships on, each sensitive endpoint has to invoke the role check itself; the endpoints here trusted the interface to have filtered access.
When a request reaches the server, it authenticates: it reads the session, confirms the user is signed in, and answers. Authorization is the second question, whether this user is allowed to do this particular thing, and on the app's admin endpoints nobody asked it. [2][3]
The role decision had been made once, in the browser. The condition that decides whether to render the admin button ships inside the JavaScript every visitor downloads. [4] Reading it took the inspector and a search. [5] "The app never decided I wasn't allowed," the reviewer wrote. "No check failed. There was no check." [7]
The reviewer says this was not a beginner's mistake, and by his account he has built web software for over eight years. [14] He had used RBAC without exception, with separate middlewares for authentication and for role. [12] On the endpoints that mattered, the role middleware never ran. He had never asked the attacker's question: "is there a route where nobody checks?" [13]
He confirmed it with Burp's proxy, and he is careful about what the tool does. "Burp decides nothing," he wrote; it hands you a request already leaving your session and lets you send it again. [10][11] Browsing as his non-admin user, he replayed the requests the interface had made on its own, and several returned data or actions belonging to a more privileged role. [8]
The reviewer calls this broken access control, and says it needs nothing spectacular: one check living only in the interface is enough. [15] The scope was narrow and he says so. He reached administrator functionality without ever obtaining the admin password, and did not get the server, the database, or anyone's credentials. [16] "Authorization problem, not a takeover," he wrote. [17]
What to watch
- Whether the app's owner added a server-side role check to every admin endpoint after the review.
- Whether other role-gated pages in the same app also enforce access only in the browser.