Horizontal Privilege Escalation

Horizontal Privilege Escalation

Being logged in is not the same as being allowed.

What Is Horizontal Privilege Escalation?

Insecure direct object reference lives in the gap between two checks that feel like one. Session middleware proves who is calling. Nothing asks whether this caller may read this record. You'll open your own statement on a money app, change one digit in the id, and read a stranger's balance and transactions with your own valid session. Then you add the ownership comparison that returns 403 when the record's owner is not the session's user, and see why random UUIDs and rate limits are depth rather than the fix.

What You'll Learn in Horizontal Privilege Escalation

Horizontal Privilege Escalation — Training Steps

  1. A normal customer view

    Sablefin is a money app that anyone can sign up for. Bob did, with a throwaway identity, and now he is just a customer looking at his own account like everyone else. He opens his monthly statement. Nothing here is off-limits to him. It is his account, his data, his login.

  2. Watch the request

    Before Bob changes anything, he wants to see the request his own app makes to load this page. He opens the browser network tools and reloads the page, so the call the app sends to fetch his statement is captured.

  3. The endpoint and the id

    The network tools captured the call. It is a plain GET to the statements API, and the whole address of Bob's statement is a single integer on the end of the path.

  4. The token that proves who he is

    The same captured request carries Bob's session token. The server reads it to confirm the caller is a signed-in customer.

  5. Change one digit

    Bob never touches the app's interface again. He edits the captured request directly, dropping the id by one and resending it with his own token still attached. If the server hands back a statement that is not his, it never checked ownership: it trusted the id in the URL to decide what to return.

  6. Somebody else's account

    Different name, different account number, different balance, and Bob's token still on the request. The server had no reason to serve this, and it served it anyway. One adjacent id is all it takes to confirm the bug. Everything past this point is a ten-line script walking the id space overnight while Bob sleeps.

  7. Knowledge check

    You just watched a logged-in customer read another customer's statement by changing one number. Lock in why.

  8. The alert lands

    You own Sablefin's customer accounts service. Overnight, anomaly detection flagged one session pulling statement after statement across accounts that were not its own. Security operations has emailed you the details.

  9. Open the handler

    Open the statements handler and look at how it decides what to return.

  10. Spot the flaw

    The handler fetches the statement by the id in the URL and returns it. Between those two lines, the check that should be there is not.

Security Framework Coverage

OWASP Top 10

  • A01:2025 Broken Access Control
  • A01:2021 Broken Access Control

CWE

  • CWE-639 Authorization Bypass Through User-Controlled Key
  • CWE-862 Missing Authorization

CIS Controls

  • CIS 16 Application Software Security

NIST CSF

  • PR.AT-02 Individuals in specialized roles are provided with awareness and training so that they possess the knowledge and skills to perform relevant tasks with cybersecurity risks in mind
  • PR.PS Platform Security