Skip to content

Access Control

Access control, also called authorization, determines what an authenticated user is allowed to access or perform inside an application.

Broken access control happens when an application fails to properly enforce these rules. This can allow users to access other users' data, administrative functions, internal resources, or actions outside their assigned permissions.

Warning

Test access control only in authorized labs, bug bounty scopes, or systems where you have explicit permission.


Core Concepts

Access control depends on three related security areas.

Concept Question Answered Example
Authentication Who are you? Login with username and password
Session management Are you the same user who logged in? Session cookie
Access control Are you allowed to do this? Admin-only delete function

Access control checks should happen on the server side for every sensitive action.


Why Access Control Fails

Access control issues often happen because developers assume users will only interact with the application through the intended interface.

Common bad assumptions:

  • Users will not manually browse to hidden URLs.
  • Users will not change IDs in requests.
  • Hidden form fields cannot be modified.
  • Cookies cannot be edited.
  • JavaScript access checks are enough.
  • If a button is hidden, the action is protected.
  • Complex URLs are unguessable enough to be safe.

These assumptions are unsafe because attackers can intercept, modify, and replay HTTP requests.


Vertical Privilege Escalation

Vertical privilege escalation occurs when a lower-privileged user gains access to higher-privileged functionality.

Example:

Standard user -> Admin functionality

Common targets:

  • Admin panels
  • User management
  • Billing settings
  • API key generation
  • Debug consoles
  • Internal dashboards
  • Delete or modify user functions

Unprotected Functionality

Sometimes sensitive functionality is accessible directly if the user knows the URL.

Example:

GET /admin HTTP/1.1
Host: vulnerable.example

Or:

GET /admin/delete-user?id=12 HTTP/1.1
Host: vulnerable.example

If the server does not check whether the current user is an admin, hiding the link in the UI does not protect it.

Testing Idea

Try directly requesting sensitive-looking paths:

/admin
/administrator
/admin-panel
/manage
/dashboard
/internal
/debug

Information Leakage

Applications may leak hidden admin paths in places users can access.

Common sources:

  • HTML comments
  • JavaScript files
  • API responses
  • robots.txt
  • Sitemap files
  • Error messages
  • Frontend route definitions

Example robots.txt:

User-agent: *
Disallow: /administrator-panel

This prevents search engines from indexing the path, but it also reveals the path to anyone who reads the file.


Security by Obscurity

A hidden or random-looking URL is not enough.

Example:

/administrator-panel-yb556

This may seem hard to guess, but it is still insecure if:

  • The URL appears in JavaScript
  • The URL appears in page source
  • The URL appears in logs
  • The URL is shared with all users
  • The server does not enforce authorization

The rule is simple:

Hidden path != protected path

Parameter-Based Access Control

Some applications trust request parameters, cookies, or hidden fields to determine privileges.

Bad examples:

GET /home.jsp?admin=false HTTP/1.1
Cookie: role=user
<input type="hidden" name="isAdmin" value="false">

An attacker can modify these values:

GET /home.jsp?admin=true HTTP/1.1
Cookie: role=admin

Access control decisions should not trust user-controlled input.


Horizontal Privilege Escalation

Horizontal privilege escalation occurs when a user accesses another user's resources without gaining higher privileges.

Example:

User A -> User B's account data

This is commonly caused by IDOR vulnerabilities.


IDOR

IDOR stands for Insecure Direct Object Reference.

It happens when an application exposes a direct reference to an object, such as a user ID, file ID, invoice ID, or order ID, without checking whether the current user is allowed to access it.

Example:

GET /my-account?id=123 HTTP/1.1
Host: vulnerable.example
Cookie: session=user-a

The attacker changes the ID:

GET /my-account?id=456 HTTP/1.1
Host: vulnerable.example
Cookie: session=user-a

If the application returns user 456's account data, access control is broken.


Common IDOR Targets

Look for object identifiers in:

  • URL paths
  • Query parameters
  • JSON bodies
  • Form fields
  • Cookies
  • API routes
  • File download links

Examples:

/user/123
/account?id=123
/api/users/123
/download?fileId=123
/order/9001
/invoice?id=INV-1001

GUIDs and UUIDs

Some applications use GUIDs or UUIDs instead of sequential IDs.

Example:

/api/users/8f14e45f-ea3f-42c0-a5d5-123456789abc

This is harder to guess than 123, but it is not automatically secure.

GUID-based access control can still fail if:

  • GUIDs are leaked in public pages
  • GUIDs appear in JavaScript
  • GUIDs appear in API responses
  • GUIDs are predictable
  • The application still does not verify ownership

Horizontal to Vertical Escalation

Attackers can sometimes chain horizontal access into vertical escalation.

Example attack path:

  1. A normal user finds an IDOR in account settings.
  2. The user changes id=123 to id=456.
  3. User 456 is an administrator.
  4. The attacker accesses the admin user's account settings.
  5. The attacker changes the admin email or resets credentials.
  6. The attacker gains administrative access.

This chain starts as horizontal privilege escalation and becomes vertical privilege escalation.


Testing Checklist

When testing access control, ask:

  • Can a normal user access admin URLs directly?
  • Are hidden URLs leaked in source code?
  • Can IDs be changed to access other users' data?
  • Are authorization checks enforced server-side?
  • Can cookies or parameters change user role?
  • Can lower-privileged users call privileged API endpoints?
  • Can users modify or delete objects they do not own?
  • Are different HTTP methods protected consistently?
  • Are GUIDs or UUIDs leaked anywhere?
  • Are API responses exposing more data than the UI shows?

Remediation

Strong access control should be enforced consistently on the server side.

Good practices:

  • Deny access by default.
  • Check authorization on every sensitive request.
  • Do not rely on hidden buttons or hidden URLs.
  • Do not trust user-controlled role values.
  • Use server-side session identity.
  • Verify object ownership before access.
  • Use centralized authorization logic.
  • Log access control violations.
  • Test with multiple user roles.
  • Apply least privilege.

Example rule:

Before returning invoice 123,
verify that the current user owns invoice 123
or has an authorized role to view it.

Quick Reference

Issue Example Impact
Unprotected admin route /admin accessible to normal user Vertical escalation
IDOR Change user_id=1 to user_id=2 Horizontal escalation
Role parameter trust admin=false changed to admin=true Vertical escalation
Leaked admin URL Path exposed in JavaScript Admin function discovery
GUID leakage User UUID exposed publicly IDOR despite unguessable IDs

Notes to Remember

  • Authentication proves identity.
  • Session management tracks identity.
  • Access control decides permissions.
  • Access control must be enforced server-side.
  • Hidden links are not security.
  • User-controlled parameters must not define privileges.
  • IDOR is one of the most common access control flaws.
  • GUIDs help prevent guessing but do not replace authorization.