The commonest flaw in client portals is invisible to every scanner

  • 2 min di lettura

A client portal. A real user, properly logged in, opens one of their documents. The address is something like /api/documents/4187.

They change the number. 4186. And they see another company’s signed contract.

It is the top entry in the OWASP API list, it is called Broken Object Level Authorization, and we find it in a good proportion of the portals we get called about.

Why no scanner finds it

Because technically there is no error. The program does exactly what it was asked: it was asked for document 4186, and it returns document 4186. It does not crash, it produces no warning, it answers 200.

An automated tool looks for known patterns: unfiltered input, old versions, bad configuration. It cannot know that the document does not belong to whoever is asking, because that fact lives in your business model, not in the code.

How it gets written by accident

Like this:

if (!user_is_logged_in()) {
    return null;
}

return db()->row('SELECT * FROM documents WHERE id = ?', [$id]);

There is a check, and it is the one everybody expects to see: no login, no entry. But the question the last line answers is “does document 4186 exist?”, not “does document 4186 belong to whoever is asking?”.

How it gets closed

$user = user_is_logged_in();
if (!$user) {
    return null;
}

return db()->row(
    'SELECT * FROM documents WHERE id = ? AND client_id = ?',
    [$id, $user->client_id]
);

The fix does not add a check: it removes the possibility of forgetting one.

As long as authorisation is an if written next to the query, sooner or later someone will write a new query without that if beside it — maybe in two years, maybe a different supplier. Put inside the query, the wrong question can no longer be asked.

And there is a useful side effect: anyone trying a random number gets a 404, so they do not even learn that the number corresponds to anything.

How to check yours

It takes a person, two test accounts and half an hour. Open something with the first account, take the address, and try it again with the second. If you can see the first account’s document, you have found it.

You do not need to be technical to run that test. You only need to run it.