Skip to contentExploitQuest

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

The Check That Never Ran

Broken object-level authorisation is one missing sentence: the app confirms who you are and never confirms that what you asked for belongs to you. See the gap once and you will look for it everywhere.

2 min read

Not yet reviewed

Wrenlearner

I signed in. The app knows it is me. So when I ask for a record, is it not already safe?

Rookmentor

It knows *who* you are. That is authentication. Whether you are allowed *this particular record* is a second question — authorisation — and it is the one applications forget to ask.

Two questions, not one

Every request for a specific thing asks two questions of the server. Who are you? — answered by your session. And is this thing yours to see? — answered by comparing the thing's owner to you. The first question is hard to get wrong; a logged-out user is turned away. The second is easy to skip, because the code that answers the first *feels* like enough.

Broken object-level authorisation — IDOR, in the old name — is what happens when only the first question is asked. You are logged in, so the door opens; and once it is open, the application fetches whatever id you named, without checking the name on it.

The check that runs

if (!session) return redirect('/login')
return statementFor(params.id)

The check that is missing

if (!session) return redirect('/login')
if (account(params.id).owner !== session.user) return forbidden()
return statementFor(params.id)

One line. The application on the left is not missing a firewall or a library — it is missing a sentence that compares the object's owner to the person asking. The id came from the URL, and the URL is yours to edit.

The id is just a number in the address bar. Why is trusting it such a common mistake, when nobody would trust a password typed into a URL?