Skip to contentExploitQuest

Lesson 2 of 3 in Broken Access Control · 3 min left in this chapter

Walk To The Account

A real back office, a real login, and one number in the address bar between you and an account you do not own. You will change it, read what was never meant for you, and see the missing check for yourself.

3 min read

Not yet reviewed

Rookmentor

There is a lab attached to this chapter: the Northwind Ledger, a bank's internal back office. You get an ordinary analyst's login. Use it, and then go somewhere it did not mean to let you.

Wrenlearner

An analyst login. So I only see my own accounts?

Rookmentor

That is what the menu offers you. It is not what the server enforces. The menu is a suggestion; the URL is the truth.

Signing in

Open the lab in a new tab — a broken-access-control lab needs a real browser session, because you are going to log in and then move around. Sign in with the analyst account:

email     [email protected]
password  spring2023
  1. Line 1An ordinary analyst. Not an administrator, not a controller — exactly the kind of low-privilege account an attacker usually starts from.

The three moves

Broken object-level authorisation is even simpler than injection, because there is no payload. The whole attack is:

1  open your own statement, and look at the address bar
2  find the account id in it
3  change it to one you do not own — the operating account, 9000
  1. Line 1From the dashboard, open your expenses account's statement. The URL now ends in your account's id. That id is the only thing selecting whose statement you see.
  2. Line 2It is not hidden, hashed, or signed. It is a plain number, because the developer thought of it as a lookup key rather than a permission.
  3. Line 3The operating account belongs to the controller, not to you. Change the id to 9000 and load it. The server checks that you are logged in — you are — and hands it over.

Now do it

Read the operating account's statement. Among its transactions is a wire with a payout reference — a value an analyst was never meant to see. That reference is your flag. It is unique to you, so copy the one *your* session shows and submit it here.

You changed the id and the statement loaded. No error, no warning. Should an attacker take the silence as a sign they did something clever?

What actually went wrong

The application asked "are you logged in?" and never asked "is this account yours?". The id came straight from the URL into the lookup, and the lookup trusted it. There is nothing to escape and nothing to encode differently — the request was valid. What is missing is a comparison, and it has to happen on the object, every single time one is fetched.