Forced Browsing and Client-Side Access Control: The Hidden Admin Page

Fondamentaux de la Sécurité Niveau 1/5 ~2 min 2026-06-25

Le défi

Voici un tableau de bord client. L'app cache ses outils admin avec du CSS - mais caché ne veut pas dire absent : les liens partent quand même dans la page. Ouvrez Afficher la source, trouvez la route réservée au personnel, et tapez l'URL vers laquelle elle pointe.

Ce que tu vas apprendre

  • Understand forced browsing and how attackers reach pages that are never linked from the visible UI
  • Recognize that CSS hiding (display:none), removed menu items, and disabled buttons are presentation, not authorization
  • Read shipped HTML the way an attacker does, treating every link and route in the source as reachable
  • Explain why access control must live on the server at the route, not in the browser
  • Map this client-side control weakness to the broken access control category of web vulnerabilities

Compétences testées

Reading and inspecting rendered HTML for routes that the UI hidesReasoning about trust boundaries between browser and serverIdentifying broken access control caused by client-side-only enforcement

Prérequis

  • Basic familiarity with HTML links and how a browser loads a page
  • Comfort using a browser to view page source or an element inspector

Comment ça marche

Forced browsing is the simple act of requesting a page or route directly, even when nothing in the visible interface links to it. An application that hides a control with CSS - display:none, a class that collapses an element, a menu item dropped at render time, or a button rendered as disabled - has changed only what the browser paints. The underlying link, URL, and route still ship inside the HTML that every visitor downloads. Anyone can open view-source or an element inspector, read the markup, and follow the route by hand.

The core mistake is treating the browser as a trust boundary. The browser is fully controlled by the person using it. CSS, JavaScript gating, and hidden DOM nodes are presentation and convenience, never security. If the only thing standing between a customer and a privileged page is styling that hides the link, then the privileged page is effectively public: it is one inspection and one click away.

This is the textbook shape of broken access control. The server happily serves the privileged route to any authenticated session because it never re-checks who is asking. Hiding the entry point lowers discoverability, but discoverability is not authorization. The moment the route is requested, the server must decide whether this specific session is allowed - and a UI that merely hides links makes no such decision.

Erreurs fréquentes

  • Assuming that because a link is not shown in the menu, the route behind it is unreachable - the markup ships to every browser regardless of styling.
  • Relying on display:none, a disabled button, or a removed list item as an access control, when these only change what is painted, not what is served.
  • Adding JavaScript checks that hide or block UI for non-staff users, forgetting that the attacker controls the browser and can skip the script entirely.
  • Trusting a client-supplied role, flag, or cookie value to decide what to show, instead of looking up the real role server-side on every request.

Comment s'en protéger

Enforce authorization on the server, at the route itself, on every request. Before serving any privileged page or action, the server must read the authenticated session, look up that user's real role from trusted storage, and reject the request when the role is not permitted. Done correctly, an unhidden or guessed link simply leads to a denial, so leaking the link in the HTML stops mattering.

  • Gate every admin route with a server-side role check (deny by default; allow only verified staff sessions).
  • Re-check authorization on the action endpoints too, not just the page that renders them, since attackers call those endpoints directly.
  • Never trust a role or permission value sent by the client; derive it from the session on the server.
  • Treat client-side hiding as a usability nicety layered on top of real server-side checks, never as a substitute for them.

Solution complète

Les membres Pro et Max débloquent la solution complète étape par étape.

Passer Pro

Statistiques de la communauté

47 résolutions
77% taux de réussite
Malekith Premier sang

Go deeper

Hacks du jour associés

14 000+ Hackers 100+ Labs & Cours Gratuit
Commencer Gratuitement