Research / Authorization

Authenticating the interface is not authenticating the system

A login screen protects a login screen. When the API behind it will answer without the same checks, the gate is on the door and the wall has a hole.

Kahu Labs ResearchJune 25, 2026Authorization7 min read
The short version

A common and dangerous split: the user interface is properly gated behind single sign-on, and the API it talks to will answer the same requests without any authentication at all. The front end looks locked. The system is open. We have found a portal that redirected to an identity provider before showing its screens, while the endpoint those screens called accepted requests directly, no login required. The gate was real. It was just on the wrong layer.

The system assumption

The assumption is that the interface is the system, so protecting the interface protects the system. Sign-on is added to the front end, the pages redirect to an identity provider, and the experience of using the product now requires a login. From the browser, everything is gated. But the browser is only one client of the API, and the API is the real system. An attacker does not use your interface. They talk to the endpoint directly, and the endpoint has its own opinion about whether a caller is allowed, which may be no opinion at all.

Where the assumption breaks

It breaks the moment someone calls the API without going through the UI. The interface's login redirect is client-side choreography: it decides what the browser renders. It does not, by itself, decide what the server will answer. If authorization was implemented as "the UI won't show this unless you are logged in," rather than "the endpoint won't answer this unless you are authorized," then skipping the UI skips the check. Reading the front-end code usually reveals the endpoints directly, and calling them is a single request. The SSO screen never enters the picture.

Reconstructing it

  through the UI (looks secure):
     browser -> /portal -> 302 to identity provider -> login -> app

  straight to the API (what the attacker does):
     POST /api/action  { ... }        # no session, no SSO
     HTTP/1.1 200 OK                  # the endpoint answered anyway

  the login gated the pages. it did not gate the endpoint.
The redirect protects the interface. The API was a separate decision, and it was left open.

Why the obvious defenses didn't solve it

Single sign-on on the front end. SSO here authenticates access to the interface. It is genuine and useful, and it stops at the browser. It cannot protect an endpoint that does not check for its result. An SSO redirect the API never consults is decoration from the API's point of view.

An unadvertised or non-obvious endpoint. Relying on the API path being unknown is not authentication. Endpoints are enumerable from the front-end bundle, from network traffic, and from documentation. Obscurity delays a curious attacker by minutes.

Client-side gating. Hiding actions the user is not allowed to take, in the interface, controls what the honest user sees. It has no effect on a request crafted by hand. Anything enforced only in the client is not enforced.

Root cause

The root cause is that authorization was placed at the interface rather than at the boundary the interface is only one client of. The API is the trust boundary, because it is what actually performs privileged work, and every request to it must independently establish who is calling and whether they are allowed, regardless of how they arrived. The UI's job is user experience: show the login, hide the buttons a user cannot use. The API's job is enforcement: refuse the work unless the caller proves entitlement. When enforcement is delegated to the UI, the system trusts its own front end to be the only way in, and it never is.

How to test for this class of failure

  • Take the requests the authenticated UI makes and replay them with no session at all. Anything that still succeeds was gated only in the browser.
  • Enumerate endpoints from the front-end code and documentation, then call them directly, unauthenticated and as a low-privilege user, rather than only navigating through the UI.
  • Test state-changing actions, not just reads. The most serious version is an unauthenticated endpoint that does something, not merely one that returns data.
  • Check every entry point to the same backend: mobile clients, partner integrations, and legacy paths may reach endpoints the main UI's login never covered.

How to design the control correctly

  • Enforce at the API, on every request. Each endpoint independently authenticates the caller and authorizes the action, treating the request as if it arrived with no help from any interface.
  • Make the UI a client, not a guard. Front-end gating is for experience only. Never let it be the sole thing standing between a request and privileged work.
  • Default endpoints to deny. New routes require authentication and authorization by default, so forgetting to add a check fails closed rather than open.
  • Cover all clients uniformly. Apply the same server-side checks to every path into the backend, so an alternative client cannot reach an endpoint the primary UI's login was assumed to protect.

What we took away from it

This failure is a clean illustration of a single principle: the boundary you must defend is the one where the work actually happens, not the one the user happens to see. A login screen is the most visible security control in a product, which is exactly why it is tempting to treat it as the whole of security. It is not. It protects a screen. The system is protected only when the API behind that screen refuses to work for a caller it has not independently authorized. We test from the API's point of view for this reason, because that is the point of view the attacker takes.

References

  1. OWASP API Security Top 10 (2023): API2 Broken Authentication
  2. OWASP: REST Security Cheat Sheet
  3. CWE-306: Missing Authentication for Critical Function
  4. CWE-425: Direct Request (Forced Browsing)

Internal evidence: Kahu Labs Research, anonymized authorized assessments (2025). Client, target and identifying details are withheld; see our research policy.