Direct naar inhoud

Insecure direct object reference (IDOR)

CWE-639OWASP A01:2021Bijgewerkt 29 augustus 20265 min leestijd

Bij een insecure direct object reference (IDOR) verwijst een applicatie met een ID rechtstreeks naar een object, maar controleert ze niet of de ingelogde gebruiker dat object mag zien. Wie bijvoorbeeld factuurnummer 1042 in 1043 verandert, opent zo andermans gegevens.

Een insecure direct object reference (IDOR) is een klassieker onder de kwetsbaarheden in webapplicaties en API’s: technisch simpel, breed aanwezig en vaak pijnlijk in de gevolgen. De applicatie laat gebruikers via een ID rechtstreeks naar objecten verwijzen (facturen, dossiers, foto’s) maar controleert niet of de aanvrager dat object wel mag zien. Wie het ID aanpast, kijkt in andermans gegevens.

Wat is een insecure direct object reference?

Een IDOR ontstaat wanneer een applicatie een interne verwijzing (meestal een database-ID, soms een bestandsnaam of klantnummer) direct in de URL, een formulier of een API-verzoek zet, en de toegang vervolgens alleen baseert op de vraag óf iemand is ingelogd, niet op de vraag of déze gebruiker dít object mag benaderen. De authenticatie is dan op orde, maar de autorisatie op objectniveau ontbreekt.

Vergelijk het met een garderobe zonder controle: wie nummer 87 roept, krijgt jas 87 mee, ook met bonnetje 12 in de hand. De garderobemedewerker controleert wél dat u een bonnetje hebt (authenticatie), maar niet of dat bonnetje bij de jas hoort (autorisatie).

In de OWASP Top 10 valt IDOR onder A01:2021 (Broken Access Control), de meest voorkomende categorie kwetsbaarheden. In API-context wordt hetzelfde probleem vaak BOLA genoemd: broken object level authorization. MITRE registreert het als CWE-639, “Authorization Bypass Through User-Controlled Key”.

Hoe werkt een IDOR-aanval?

Een aanvaller heeft meestal genoeg aan een eigen, legitiem account. Daarmee bekijkt hij hoe de applicatie objecten aanwijst, bijvoorbeeld GET /api/invoices/1042 voor de eigen factuur. Vervolgens verandert hij het nummer in 1043, 1044, enzovoort. Reageert de server met andermans factuur in plaats van een foutmelding, dan is de IDOR een feit. Met een simpel script zijn zo duizenden objecten per uur te oogsten, zeker bij oplopende, voorspelbare ID’s.

De kwetsbare verwijzing hoeft niet in het URL-pad te zitten. Ook queryparameters, verborgen formuliervelden, JSON-velden in een POST-body, cookies en bestandsnamen van downloads zijn geliefde plekken. En het blijft niet bij lezen: dezelfde fout in een update- of delete-endpoint laat een aanvaller andermans gegevens wijzigen of verwijderen.

Een concreet voorbeeld uit een Node.js/Express-API:

Kwetsbaar:

// GET /api/invoices/:id
app.get("/api/invoices/:id", requireLogin, async (req, res) => {
  // Haalt de factuur op die in de URL staat - van wie die ook is
  const invoice = await db.invoices.findById(req.params.id);
  if (!invoice) return res.status(404).end();
  res.json(invoice);
});

De middleware requireLogin controleert netjes dat er een sessie is, maar de query haalt daarna elk willekeurig ID op. De veilige variant koppelt de zoekopdracht aan de ingelogde gebruiker:

Veilig:

// GET /api/invoices/:id
app.get("/api/invoices/:id", requireLogin, async (req, res) => {
  // Zoek alleen binnen de facturen van de ingelogde gebruiker
  const invoice = await db.invoices.findOne({
    id: req.params.id,
    ownerId: req.user.id,
  });
  if (!invoice) return res.status(404).end();
  res.json(invoice);
});

Bestaat de factuur wel maar hoort die bij iemand anders, dan krijgt de aanvrager nu dezelfde 404 als bij een niet-bestaand ID. Er lekt dus ook geen informatie over welke nummers in gebruik zijn. Dezelfde controle hoort thuis in elk endpoint dat een object leest, wijzigt of verwijdert.

Wat is de impact van een IDOR-kwetsbaarheid?

Alleen al leestoegang is ernstig: persoonsgegevens, facturen, medische dossiers of contracten liggen op straat. Omdat ID’s vaak oplopen, schaalt zo’n lek moeiteloos van één record naar de complete dataset. Voor organisaties die persoonsgegevens verwerken betekent dat al snel een meldplichtig datalek onder de AVG, met toezichthouder, klantcommunicatie en reputatieschade als gevolg. Het bekendste voorbeeld is de Amerikaanse titelverzekeraar First American, waar in 2019 zo’n 885 miljoen documenten met hypotheek- en persoonsgegevens via oplopende documentnummers vrij opvraagbaar bleken.

Bij schrijftoegang wordt het erger. Een aanvaller die andermans profiel kan bewerken, wijzigt bijvoorbeeld het e-mailadres van een slachtoffer en neemt het account daarna over via een wachtwoordreset. IDOR is daarmee een veelgebruikte opstap naar volledige accountovername en fraude.

Beveiligingsonderzoekers onderscheiden horizontale escalatie (toegang tot gegevens van gelijkwaardige gebruikers) en verticale escalatie (toegang tot beheerfuncties). IDOR-bevindingen scoren daarom doorgaans medium tot high, afhankelijk van de gevoeligheid van de data en of er ook geschreven kan worden.

Hoe spoort u IDOR op?

Geautomatiseerde scanners vinden IDOR zelden betrouwbaar: een scanner weet niet welk object bij welke gebruiker hoort, en een geldige respons ziet er voor een tool precies zo uit als een lek. IDOR opsporen is daarom vooral mensenwerk:

  • Test met twee (of meer) accounts: voer elke actie uit als gebruiker A en speel het verzoek na met de sessie van gebruiker B en de ID’s van A.
  • Loop systematisch alle objectverwijzingen na: URL-paden, queryparameters, POST-bodies, verborgen velden, export- en downloadlinks.
  • Gebruik tooling zoals Burp Suite (Repeater, of de extensie Autorize) om verzoeken met verwisselde sessies te herhalen.
  • Let ook op indirecte routes: rapportages, PDF-generatoren, zoek-endpoints en oude API-versies vergeten de controle opvallend vaak.

Bij een pentest van AssistSec is dit een vast onderdeel: elke objectverwijzing wordt met meerdere testaccounts nagespeeld, juist omdat deze categorie aan geautomatiseerde tooling ontsnapt. Ook in productie is detectie mogelijk: reeksen 403- of 404-responses op oplopende ID’s in de logs wijzen op enumeratie.

Hoe voorkomt u IDOR?

De remedie is conceptueel eenvoudig: controleer bij elk objectverzoek server-side of de aanvrager dat specifieke object mag benaderen.

  • Voer autorisatie op objectniveau uit bij elke lees-, schrijf- en verwijderactie, nooit alleen bij het inloggen.
  • Scope databasequeries standaard op de eigenaar of tenant (ownerId, organisatie-ID), zoals in het voorbeeld hierboven.
  • Centraliseer de controle in middleware of policy-classes, zodat een vergeten check in één endpoint niet meteen een lek is.
  • Hanteer deny by default: geen expliciete toestemming betekent geen toegang, beantwoord met een neutrale 404.
  • Vervang voorspelbare, oplopende ID’s waar mogelijk door onvoorspelbare (UUID’s), als extra drempel.
  • Neem multi-user-tests op in de CI: een integratietest die met account B de objecten van account A opvraagt, voorkomt regressie.
  • Maak autorisatie een vast punt in de codereview van elk nieuw endpoint.
Onvoorspelbare ID’s zoals UUID’s maken raden lastiger, maar lossen het onderliggende probleem niet op: zodra een ID lekt (via een e-mail, logbestand of referer-header) is het object alsnog voor iedereen toegankelijk. De enige echte oplossing is een autorisatiecontrole per object.

Bronnen

Veelgestelde vragen

Is IDOR hetzelfde als BOLA?

Vrijwel. BOLA (broken object level authorization) is de term uit de OWASP API Security Top 10 voor hetzelfde probleem in API's: ontbrekende autorisatie op objectniveau.

Helpen UUID's tegen IDOR?

Slechts gedeeltelijk. Onvoorspelbare ID's maken raden lastiger, maar zodra een ID lekt is het object alsnog toegankelijk. Alleen een autorisatiecontrole per object lost het echt op.

Hoe gevaarlijk is IDOR?

Doorgaans medium tot high. Bij toegang tot gevoelige gegevens of schrijfrechten kan een enkele aangepaste ID leiden tot een groot datalek of een accountovername.

Kan een scanner IDOR automatisch vinden?

Zelden betrouwbaar. Een scanner weet niet welke gebruiker bij welk object hoort; handmatig testen met meerdere accounts blijft de effectiefste methode.

Verwante artikelen

Druk op / om te zoeken · Esc