Broken Access Control: The Complete Practical Guide
Referer and Location-Based Access Control Bypass
Why Referer must never be an authorization control: forging the Referer header, abusing location and redirect-based gating, and combining with forced browsing.
Published
Some apps try to protect an action by checking where you came from, the Referer header, or a redirect target, or a location value. The problem is that all of those are client-controlled, so they prove nothing about your permission. Forging them is trivial, which makes Referer-based and location-based gating one of the weakest access controls there is.
Why Referer must never be an authorization control
The Referer header is supposed to tell the server which page linked to the current request. It is set by the browser, and it can be set, changed, or omitted by anyone. Using it to decide access means trusting the attacker to honestly report their own origin. It is a convenience signal, never a security boundary, and any gate built on it is bypassable by definition.
Forging the Referer
If an admin action only works when you arrive from an allowed page, supply that page as the Referer on a direct request:
POST /admin/deleteUser?id=5 HTTP/1.1
Referer: https://target.example/adminSome gates are even weaker and only check that a Referer is present, or that it is same-host:
Referer: https://target.example/Either way, you craft the header the gate wants to see and the check passes.
Location and redirect-based gating
A related mistake is gating on a client-supplied location or redirect value, trusting a next, returnUrl, or location parameter to represent a legitimate flow. If the app decides what you may do based on where it thinks you are going, and you control that value, you steer the decision:
GET /admin?next=/admin/dashboard -> the gate trusts the client-set destinationAny authorization that depends on a client-provided location is the same bug as trusting the Referer.
Combining with forced browsing
These bypasses pair naturally with forced browsing, requesting privileged URLs the UI hides. The UI would normally reach the action through a menu, which happens to set an acceptable Referer. You skip the menu, request the endpoint directly, and attach the forged Referer yourself:
POST /admin/config/reset HTTP/1.1
Referer: https://target.example/admin/configThe forced request reaches the gated action, and the forged header satisfies the only check standing in the way.
The fix and the mindset
The defense is to never use the Referer, a redirect target, or any client-supplied location as an authorization control. Decide access from the authenticated session and server-side permissions, every request. As an attacker, whenever an action only works "from" a certain page, suspect a Referer or location check and forge it. From here, these weak gates often sit in front of actions that chain into bigger wins, which is account-takeover chains. Practice forging the Referer on a free live target.
← Back to Broken Access Control: The Complete Practical Guide