Tamper the Invoice ID: An IDOR / Broken Object Level Authorization Walkthrough

Sécurité Web & API Niveau 2/5 ~60 s 2026-06-21

Le défi

Voici la requête exacte que votre navigateur a envoyée pour charger votre propre facture, la #1019. Le serveur a vérifié votre cookie de session - mais a-t-il vérifié que la facture est la vôtre ? Toute la requête est modifiable : trouvez quoi changer pour lire la facture #1020.

Ce que tu vas apprendre

  • Recognize an insecure direct object reference (IDOR) where a record id is trusted straight from the request
  • Distinguish authentication (who you are) from authorization (what you are allowed to access)
  • Tamper a single parameter in a captured HTTP request and replay it to reach another user's object
  • Read an HTTP/JSON response to confirm you received a record that is not yours
  • Explain why a per-object ownership check is the correct fix, not a stricter login

Compétences testées

HTTP request interception and parameter tampering (Burp-style editing)Identifying broken object level authorization (BOLA / IDOR)Reading and interpreting JSON API responsesReasoning about access-control logic in web APIs

Prérequis

  • Basic understanding of an HTTP request (method, path, query string, headers, cookies)
  • Familiarity with how a session cookie authenticates a logged-in user
  • Comfort reading a small JSON response body

Comment ça marche

An insecure direct object reference (IDOR) happens when an application exposes a reference to an internal object - a database row, a file, an invoice - directly in the request and then trusts that reference without checking that the caller is allowed to access that specific object. The classic shape is a numeric id in a URL or query string, such as /api/invoice?id=1019. Because the id is sequential and predictable, an attacker can simply change it to a neighbouring value and ask for someone else's record.

The subtle part is that the endpoint is not unauthenticated. The server happily validated the session cookie, so it knows which user is calling. The mistake is that it stopped there: it never asked the second question - does this invoice actually belong to the logged-in user? Checking identity (authentication) is not the same as checking permission to a specific object (authorization). When that per-object check is missing, the flaw is also called broken object level authorization (BOLA), the number-one risk in the OWASP API Security Top 10.

This challenge models that exact gap. You hold a real, captured request for your own invoice. The id sits in the request as plain, editable text, and nothing about the response format hints that the server distinguishes your records from anyone else's - which is precisely the tell that authorization is being skipped.

Erreurs fréquentes

  • Assuming a valid login is enough. Many learners see the session cookie and conclude the endpoint is safe. Authentication only proves who is calling; it says nothing about which objects that caller may read.
  • Editing the wrong part of the request. The whole request is editable, but the endpoint behaves like the real thing: tamper the session cookie and you get a 401, change the Host and you get a 404. Only the object reference - the id, with the session and host left intact - hands you another customer's invoice.
  • Stopping at a 404 and giving up. A not-found response just means that id does not exist; it is feedback, not a wall. Adjust the id to a value that is likely to be a real, neighbouring record.
  • Treating IDOR as an injection bug. No special characters, encoding, or payload are needed. You change a legitimate id to another legitimate id - the vulnerability is missing access control, not unsanitized input.

Comment s'en protéger

The fix is an object-level ownership check on every access. After the session is authenticated, the server must confirm the requested object belongs to (or is shared with) that user before returning it - for example, scoping the query to the caller: SELECT * FROM invoice WHERE id = ? AND owner_user_id = :sessionUser. If the row does not match, return 404 or 403 and never the data. Tightening the login flow does nothing here, because the attacker is already logged in.

  • Enforce authorization per object on the server; never rely on the client only requesting ids it "should" know.
  • Prefer unpredictable identifiers (UUIDs) over sequential integers to remove the easy enumeration, while still keeping the ownership check - obscurity alone is not access control.
  • Log and alert on access attempts that fail the ownership check, especially sequential id sweeps.

Solution complète

Les membres Pro et Max débloquent la solution complète étape par étape.

Passer Pro

Statistiques de la communauté

47 résolutions
77% taux de réussite
Malekith Premier sang

Go deeper

13 000+ Hackers 100+ Labs & Cours Gratuit
Commencer Gratuitement