Le premier vrai bug que la plupart des gens trouvent est une vulnérabilité IDOR, et ils la trouvent en général en changeant un seul chiffre. Vous ouvrez votre propre commande sur /orders/4417, vous tapez 4418 par curiosité, et l'adresse de livraison d'un inconnu s'affiche. Pas de payload, pas d'astuce d'encodage, pas de code d'exploitation. Juste un nombre auquel le serveur a fait confiance. Si vous voulez ressentir ce moment avant d'en lire un mot de plus, ouvrez le lab IDOR Explorer de HackerDNA et commencez à permuter des identifiants.
L'IDOR appartient au contrôle d'accès défaillant, première entrée de l'OWASP Top 10, et c'est la faille la plus souvent signalée sur les programmes de bug bounty pour une bonne raison : il se teste en dix secondes et les développeurs continuent d'en livrer. Ce guide couvre ce qu'est réellement un IDOR, comment le chasser correctement, les « correctifs » qui ne corrigent rien, et comment refermer le trou pour de bon.
À retenir : une vulnérabilité IDOR (Insecure Direct Object Reference, référence directe d'objet non sécurisée) survient quand une application reçoit un identifiant de l'utilisateur, va chercher l'objet correspondant, et ne vérifie jamais si cet utilisateur a le droit de l'obtenir. Le bug n'est pas la référence. C'est la vérification de propriété manquante. On trouve les IDOR en gardant deux comptes côte à côte et en rejouant les requêtes du compte A avec les identifiants du compte B, et on les corrige par une vérification côté serveur liée à la session, pas en rendant les identifiants plus difficiles à deviner.
Qu'est-ce qu'une vulnérabilité IDOR ?
IDOR signifie Insecure Direct Object Reference, soit référence directe d'objet non sécurisée. C'est une faille de contrôle d'accès où une application expose une référence vers un objet interne (une ligne de base de données, un fichier, un document) et laisse n'importe quel utilisateur connecté fournir cette référence sans vérifier qu'il en est propriétaire. Changez la référence, recevez un autre objet.
Coupez le nom en deux et il s'explique tout seul. Une référence directe d'objet est normale et inévitable : toute application a besoin d'une manière de dire « donne-moi l'enregistrement 4417 ». La partie non sécurisée, c'est la vérification d'autorisation manquante. Votre application n'est pas cassée parce que 4417 apparaît dans l'URL. Elle est cassée parce que le serveur n'a jamais demandé si la personne qui réclame 4417 a la moindre raison de le voir.
Techniquement, cela correspond à CWE-639 : Authorization Bypass Through User-Controlled Key, que MITRE classe comme ayant une forte probabilité d'exploitation. MITRE liste « Insecure Direct Object Reference (IDOR) » et « Broken Object Level Authorization (BOLA) » comme noms alternatifs de la même faiblesse : si vous croisez ces trois termes dans un rapport, ils décrivent le même échec.
La version courte que tout débutant devrait retenir : l'authentification demande qui vous êtes, l'autorisation demande ce que vous avez le droit de toucher. Un IDOR, c'est une application qui a réussi la première question et sauté la seconde.
Comment fonctionne une attaque IDOR, étape par étape
Comment fonctionne une attaque IDOR ? Vous vous connectez comme utilisateur légitime, vous trouvez une requête qui transporte un identifiant que vous contrôlez, vous remplacez cet identifiant par celui de quelqu'un d'autre, et vous l'envoyez. Si le serveur renvoie ses données au lieu d'une erreur, le contrôle d'accès est défaillant. Il n'y a aucun contournement de la connexion, parce que vous n'en avez jamais eu besoin.
Voici l'échange complet. Vous êtes connecté à un portail de support comme client ordinaire et vous ouvrez l'un de vos propres tickets :
GET /api/tickets/4417 HTTP/1.1
Host: helpdesk.acme.example
Cookie: session=a9f31c0b7e2d...
HTTP/1.1 200 OK
{"id":4417,"owner":"[email protected]","subject":"Refund request","body":"..."}
Vous changez un seul caractère et vous renvoyez :
GET /api/tickets/4418 HTTP/1.1
Host: helpdesk.acme.example
Cookie: session=a9f31c0b7e2d...
HTTP/1.1 200 OK
{"id":4418,"owner":"[email protected]","subject":"Card declined","body":"..."}
Le serveur a vérifié votre cookie, décidé que vous étiez connecté, puis lu le ticket 4418 dans la base parce que vous l'avez demandé. Rien dans ce chemin de code n'a comparé owner à votre session. Cet écart est toute la vulnérabilité.
- Obtenez une session authentifiée. Inscrivez-vous ou connectez-vous comme utilisateur ordinaire. Vous n'attaquez pas la connexion, vous abusez de ce qu'un compte normal peut déjà atteindre.
- Trouvez une référence que vous contrôlez. Observez le trafic et notez chaque identifiant, nom d'utilisateur, nom de fichier et numéro de référence envoyé par le navigateur. Chacun est un candidat.
- Changez-la et lisez la réponse attentivement. Un
200contenant les données de quelqu'un d'autre est un IDOR confirmé. Un403signifie que cet endpoint vérifie. Un404signifie souvent que la vérification existe et que l'application cache jusqu'à l'existence de l'enregistrement, ce qui est une bonne pratique. - Prouvez l'impact, puis arrêtez. Un seul enregistrement appartenant à un deuxième compte que vous contrôlez suffit pour le rapport. Extraire dix mille enregistrements est une fuite de données à votre nom.
Lecture, écriture et aveugle : les trois formes d'IDOR
La plupart des articles s'arrêtent à « vous pouvez lire les données des autres ». Les chasseurs de bugs posent une deuxième question : pouvez-vous aussi écrire ? C'est là toute la différence entre une fuite d'information et une prise de contrôle de compte.
IDOR en lecture (divulgation)
Une requête GET renvoie un objet qui ne vous appartient pas. Factures, dossiers médicaux, messages privés, fichiers téléversés, tickets de support. C'est la forme la plus courante et la plus facile à prouver. La gravité dépend entièrement du contenu de l'objet : le nom public d'un autre utilisateur, c'est du bruit ; son passeport scanné, c'est une faille critique.
IDOR en écriture (altération et prise de contrôle)
Un POST, un PUT ou un PATCH modifie un objet qui ne vous appartient pas. Le cas classique est l'endpoint de mise à jour de profil qui accepte un user_id dans le corps : remplacez-le par celui de quelqu'un d'autre, mettez votre adresse e-mail à la place de la sienne, puis lancez une réinitialisation de mot de passe. Cet enchaînement transforme un « moyen » en prise de contrôle complète du compte, et c'est pourquoi il faut toujours tester le chemin d'écriture même quand la lecture est correctement verrouillée.
IDOR aveugle (aucune donnée ne revient)
Certains endpoints renvoient un 200 vide ou un simple message de succès quel que soit l'objet touché. Cela ne veut pas dire que ça a échoué. Si POST /api/invites/4418/resend répond {"status":"sent"}, vérifiez qu'un e-mail est bien arrivé dans la boîte du second compte. En pratique, c'est là que les débutants abandonnent trop tôt, parce que le corps de la réponse a l'air ennuyeux et que l'effet de bord se produit quelque part où ils ne regardaient pas.
Où se cachent les IDOR dans les applications modernes
Tout le monde regarde la barre d'adresse, et c'est bien pour ça que les IDOR de la barre d'adresse ont presque disparu des applications matures et que les plus intéressants vivent ailleurs. Ces quatre endroits produisent le plus de trouvailles, à peu près par ordre de rendement.
- Les corps de requête JSON des API internes. Les applications monopage envoient bien plus de paramètres que l'URL n'en montre. Un endpoint comme
PATCH /api/v2/profiletransportant{"user_id":4417,"email":"..."}est la cible la plus rentable sur la plupart des sites, parce que le front-end envoie toujours le bon identifiant et que personne n'a testé ce qui se passe quand ce n'est pas le cas. - Les endpoints d'export, de téléchargement et de rapport. Souvent rajoutés plus tard par une autre équipe, et souvent en contournant le middleware d'autorisation que l'application principale utilise.
GET /reports/download?ref=Q3-4417.pdfmérite dix minutes de l'attention de n'importe qui. - Les en-têtes personnalisés contrôlés par le client. Certaines API passent l'identité ou le tenant dans des en-têtes comme
X-Account-Id. Si le serveur lit cet en-tête au lieu de déduire le compte de la session, vous tenez un IDOR qui n'apparaît ni dans l'URL ni dans le corps. - Les identifiants imbriqués et secondaires. Une requête comme
GET /api/teams/12/members/4417valide souvent votre appartenance à l'équipe 12, puis fait entièrement confiance à l'identifiant du membre. Changer l'identifiant externe donne un403net ; changer l'interne donne l'enregistrement. Testez chaque identifiant d'un chemin, pas seulement le dernier.
GraphQL mérite sa propre mention. Une seule requête node(id: "...") peut exposer des objets que l'API REST protège correctement, parce que l'autorisation a été écrite endpoint par endpoint et que GraphQL a réduit cent endpoints à un seul. Si une cible tourne sous GraphQL, commencez par là.
Comment tester les vulnérabilités IDOR
Comment tester une vulnérabilité IDOR ? Créez deux comptes, capturez les requêtes que le compte A envoie à ses propres ressources, puis rejouez chaque requête avec le cookie de session de A et les identifiants de B. Toute réponse qui renvoie les données de B ou modifie son état est un IDOR. Deux comptes, c'est toute la méthodologie, et c'est la partie que les scanners ne peuvent pas faire à votre place.
- Créez deux comptes et gardez-les séparés. Utilisez deux navigateurs ou deux conteneurs pour que les sessions ne se mélangent jamais. Créez un objet distinctif dans chacun (un ticket intitulé « canary-B », par exemple) pour savoir instantanément à qui appartiennent les données que vous regardez.
- Passez tout par un proxy et dressez une carte. Parcourez toute l'application via un proxy d'interception avec le compte A, puis relisez l'historique et notez chaque paramètre qui ressemble à un identifiant. Notre tutoriel Burp Suite explique comment faire dialoguer le proxy et le navigateur si vous n'en avez jamais configuré.
- Permutez dans Repeater, une requête à la fois. Remplacez l'identifiant d'objet de A par celui de B et comparez les réponses. Refaites ensuite l'exercice sans aucun cookie de session, ce qui révèle parfois un accès non authentifié que personne n'attendait.
- Automatisez la partie fastidieuse. L'extension gratuite Autorize de Burp rejoue chaque requête que vous envoyez à travers la session d'un second compte et signale celles qui auraient dû être bloquées. Elle transforme un après-midi de permutations manuelles en une liste que vous relisez en vingt minutes.
- Testez aussi les chemins d'écriture et de suppression. Un
GETbien verrouillé ne dit rien duPUTcorrespondant. Ils ont été écrits par des développeurs différents, des jours différents.
Une habitude à prendre tôt : consignez les paires de requêtes exactes au fil de l'eau. Un rapport qui montre la requête A (votre compte, votre enregistrement, 200) à côté de la requête B (votre session, l'enregistrement de l'autre, 200) est trié rapidement. Un rapport qui dit « je pouvais voir les données des autres utilisateurs » est fermé avec la mention « informations insuffisantes ».
Des correctifs qui n'en sont pas
Quand une équipe reçoit un rapport d'IDOR, le premier réflexe est en général de rendre l'identifiant plus difficile à deviner. Ce réflexe est faux, et comprendre pourquoi sépare celui qui a compris le bug de celui qui l'a mémorisé. Impossible à deviner n'est pas synonyme de non autorisé.
- Passer aux UUID. Les identifiants aléatoires augmentent le coût de l'énumération, ce qui est réellement utile, mais ce ne sont pas des vérifications de permission. Les UUID fuient en permanence : liens partagés, en-têtes de référent, exports CSV, captures d'écran envoyées au support, résultats de recherche de l'application elle-même. Dès qu'un identifiant fuit, l'endpoint qui n'a jamais vérifié la propriété ne la vérifie toujours pas.
- Encoder l'identifiant. Un paramètre valant
NDQxNw==a l'air opaque pendant environ quatre secondes. C'est le base64 de4417. Le hachage n'est guère mieux quand il n'est pas salé : un identifiant commeb1d5781111d84f7b3fe45a0852e59758cd7a87e5n'est que le SHA-1 d'un petit entier, et n'importe qui peut précalculer le premier million. - Vérifier côté client. Si le navigateur décide d'afficher ou non le bouton de modification, le serveur doit quand même décider s'il honore la requête. Les attaquants n'appuient pas sur des boutons, ils envoient des requêtes.
- Bloquer une seule méthode HTTP. Refuser
POST /admin/records/4418pendant quePUTetDELETEpassent tranquillement est un schéma qu'on rencontre vraiment dans du vrai code, généralement causé par une règle de route qui énumérait les méthodes à la main.
Une deuxième catégorie, c'est le filtre qu'un petit changement contourne. id=4418 peut être bloqué alors que id[]=4418 arrive sous forme de tableau et emprunte un autre chemin de code, et envoyer les deux avec id=4417&id=4418 désigne des gagnants différents selon les frameworks. Ce ne sont pas des attaques astucieuses. Ce sont des preuves que l'application valide une forme au lieu de vérifier une permission.
Ce que les vraies fuites par IDOR ont coûté
L'IDOR est traité comme un bug de débutant, ce qui le sous-estime largement. En juillet 2023, la CISA, la NSA et l'Australian Cyber Security Centre ont publié un avis conjoint intitulé Preventing Web Application Access Control Abuse précisément à cause des dégâts que cette seule classe de failles continuait de causer. Trois des incidents qu'il documente :
- 2019 : plus de 800 millions de fichiers financiers personnels exposés chez un organisme de services financiers américain.
- 2021 : des centaines de milliers d'appareils mobiles exposés via des applications de stalkerware contenant des failles IDOR.
- 2012 : les données personnelles de plus de 100 000 propriétaires d'appareils mobiles récupérées sur le site d'une entreprise du secteur des télécommunications.
Le cas de 2019 est celui que tout testeur web devrait connaître. First American Financial Corporation, un assureur de titres du Fortune 500, exploitait un système de partage de documents qui numérotait séquentiellement les actes de vente. Quiconque possédait le lien vers un document pouvait modifier le numéro et lire le suivant, et l'ensemble exposé remontait à 2003 : numéros de sécurité sociale, coordonnées bancaires, scans de permis de conduire. D'après la décision de la SEC de juin 2021, la propre équipe sécurité de l'entreprise avait documenté la faille lors d'un test d'intrusion manuel plusieurs mois avant sa révélation publique, et elle n'a jamais été corrigée conformément à la procédure. First American a payé 487 616 dollars pour clore la procédure sur les contrôles de communication financière.
C'est cet enchaînement qui est instructif. Le bug a été trouvé en interne, par une personne, en faisant exactement l'exercice à deux comptes décrit plus haut. Puis il est resté là. La faille technique tenait à une vérification manquante ; l'échec coûteux était organisationnel.
La classe n'a pas disparu. Le contrôle d'accès défaillant est en A01 de l'OWASP Top 10 2025, construit à partir de 40 CWE, d'environ 1,84 million d'occurrences recensées et de 32 654 CVE associées. L'OWASP place sa forme API en première position de l'API Security Top 10, en qualifiant sa prévalence de généralisée et son exploitabilité de facile.
Comment corriger une vulnérabilité IDOR
Comment corriger un IDOR ? Récupérez l'objet, puis vérifiez que la session authentifiée a le droit d'obtenir cet objet précis, avant de renvoyer quoi que ce soit. La vérification appartient au serveur, au même endroit que la récupération des données, et elle doit utiliser l'identité issue de la session plutôt qu'une valeur envoyée par le client.
Concrètement, voici la différence entre vulnérable et corrigé :
# Vulnerable: the ID decides everything
ticket = Ticket.get(request.params["id"])
return ticket.to_json()
# Fixed: ownership is part of the lookup
ticket = Ticket.get(request.params["id"])
if ticket is None or ticket.owner_id != session.user_id:
return http_404()
return ticket.to_json()
Renvoyer 404 plutôt que 403 sur une vérification échouée est un petit détail à adopter. Un 403 confirme que l'enregistrement 4418 existe, ce qui offre à un attaquant un oracle d'existence fonctionnel même quand les données restent cachées.
- Refusez par défaut. Les ressources démarrent fermées et ne s'ouvrent que par une règle explicite. Un nouvel endpoint que quelqu'un a oublié de protéger doit échouer en position fermée, pas s'ouvrir.
- Placez la vérification là où sont les données. Une passerelle qui confirme une session valide n'est pas une autorisation. Si la seule vérification vit en périphérie, chaque appel de service interne tourne sans protection.
- Centralisez la politique. Une couche d'autorisation unique que chaque requête traverse vaut mieux que des vérifications par endpoint recopiées à la main, parce que les copies dérivent et que l'une d'elles sera fausse.
- Alertez sur le schéma, pas sur la requête. Un
403est une faute de frappe. Quatre cents qui parcourent des identifiants consécutifs depuis une même session, c'est une énumération en cours, et cela doit réveiller quelqu'un.
Ajoutez un test de non-régression pendant que vous y êtes. Un test qui se connecte comme utilisateur B et vérifie un 404 sur l'objet de l'utilisateur A coûte environ six lignes et empêche la faille de revenir à la prochaine refonte du contrôleur.
IDOR, BOLA et contrôle d'accès défaillant
Trois termes, un même échec sous-jacent, des portées différentes. Les distinguer rend les rapports et les entretiens plus fluides.
Le contrôle d'accès défaillant est la catégorie parapluie. Il couvre tous les échecs d'autorisation : atteindre une page d'administration jamais accordée, élever un rôle, altérer une méthode de requête, et l'IDOR. Notre guide du contrôle d'accès défaillant en cartographie l'ensemble.
L'IDOR est un type précis à l'intérieur de ce parapluie : une référence d'objet contrôlée par l'utilisateur, récupérée sans vérification de propriété. Tout IDOR est une faille de contrôle d'accès. La plupart des failles de contrôle d'accès ne sont pas des IDOR.
BOLA (Broken Object Level Authorization) est le nom que l'OWASP donne à l'IDOR dans son API Security Top 10, où il occupe la première place. Même bug, appellation orientée API. Si un analyste de triage reclasse votre rapport d'IDOR en BOLA, rien n'a changé sauf le vocabulaire.
Considérations légales et éthiques
Rappel essentiel : obtenez toujours une autorisation écrite explicite avant de chercher des IDOR dans une application. Modifier un identifiant pour lire l'enregistrement de quelqu'un d'autre sur un système qui ne vous appartient pas constitue un accès non autorisé au regard du Computer Fraud and Abuse Act (États-Unis), du Computer Misuse Act (Royaume-Uni) et de lois équivalentes dans le monde entier. Le fait que le serveur ait répondu ne vaut pas permission, et « je n'ai changé qu'un chiffre » n'a jamais fonctionné comme défense.
- Ne testez que sur des systèmes qui vous appartiennent, sur des labs prévus pour cela, ou dans le périmètre écrit d'un programme de bug bounty ou d'une mission.
- Utilisez deux comptes que vous contrôlez. Confirmer un IDOR sur l'enregistrement d'un véritable inconnu signifie que vous avez accédé aux données d'une vraie personne, même par accident.
- Arrêtez-vous à la preuve d'impact. Un enregistrement, avec une capture d'écran, suffit pour un rapport. Parcourir toute la plage d'identifiants est une fuite de données, et les règles des programmes le disent explicitement.
- Si une réponse contient des données personnelles que vous n'attendiez pas, ne les enregistrez pas. Notez la requête, le code de statut et les noms de champs, dites-le dans le rapport, et laissez à l'équipe le temps de corriger avant toute publication.
Questions fréquentes
Que signifie IDOR ?
IDOR signifie Insecure Direct Object Reference, référence directe d'objet non sécurisée. Le terme décrit une application qui accepte de l'utilisateur une référence vers un objet (identifiant, nom de fichier ou clé) et renvoie l'objet correspondant sans vérifier que cet utilisateur est autorisé à y accéder. MITRE le suit sous CWE-639, et l'API Security Top 10 de l'OWASP appelle la même faiblesse Broken Object Level Authorization.
L'IDOR est-il encore courant en 2026 ?
Oui. Le contrôle d'accès défaillant, la catégorie à laquelle appartient l'IDOR, occupe la première place de l'OWASP Top 10 2025, à partir d'environ 1,84 million d'occurrences recensées et de 32 654 CVE. Les applications monopage et les back-ends mobiles l'ont rendu plus courant, pas moins, parce que l'autorisation doit désormais être appliquée sur des centaines d'endpoints d'API au lieu d'une poignée de pages rendues côté serveur.
Un scanner de vulnérabilités peut-il trouver un IDOR ?
Le plus souvent non. Un scanner voit qu'une requête a renvoyé 200, mais il n'a aucun moyen de savoir que l'enregistrement aurait dû appartenir à quelqu'un d'autre, parce que la propriété relève de la logique métier. Les outils qui rejouent votre trafic à travers la session d'un second compte, comme l'extension Autorize de Burp, s'en approchent bien plus, parce que vous fournissez la seconde identité qui donne son sens à la comparaison.
Les UUID empêchent-ils les vulnérabilités IDOR ?
Non. Les identifiants aléatoires ralentissent l'énumération, ce qui vaut la peine d'être fait, mais ce ne sont pas des vérifications d'autorisation. Les UUID fuient via des liens partagés, des en-têtes de référent, des exports et des captures d'écran. Si le serveur ne vérifie toujours pas que la session possède l'objet, la faille reste entière dès qu'un identifiant s'échappe.
L'IDOR est-il la même chose que le CSRF ?
Non. Dans une attaque CSRF, le navigateur d'une victime est piégé pour envoyer une requête que la victime a le droit d'envoyer. Dans un IDOR, vous envoyez depuis votre propre session authentifiée une requête que vous n'aviez pas le droit d'envoyer. Le CSRF se défend avec des jetons anti-falsification et des cookies SameSite, l'IDOR se défend avec des vérifications de propriété côté serveur.
Quelle est la gravité d'une vulnérabilité IDOR ?
La gravité dépend de l'objet et de l'action. Lire le nom affiché d'un inconnu est faible. Lire ses pièces d'identité est critique. Si la faille permet aussi d'écrire, un attaquant peut souvent changer l'adresse e-mail d'une victime et déclencher une réinitialisation de mot de passe, ce qui transforme la trouvaille en prise de contrôle complète du compte.
Fait partie de la série OWASP Top 10
Articles liés :
- Le contrôle d'accès défaillant expliqué
- Guide de la vulnérabilité IDOR
- OWASP API Security Top 10
- Tutoriel d'injection SQL
- L'attaque SSRF expliquée
Vos prochaines étapes
Une vulnérabilité IDOR est la leçon la moins chère que la sécurité applicative vous offrira jamais : un identifiant changé, une requête non vérifiée, et la différence entre authentification et autorisation cesse d'être une définition à moitié retenue. Lire à ce sujet ne fait pas grand-chose. Changer 4417 en 4418 et voir apparaître l'enregistrement d'un inconnu fait tout d'un seul coup. Commencez gratuitement, sans carte bancaire, avec le lab IDOR Explorer, puis passez à la version API dans API Breaker, où les identifiants se cachent dans le JSON plutôt que dans l'URL. Pour situer tout cela aux côtés des injections, du XSS et du reste de l'OWASP Top 10, le cours Web Attacks parcourt chaque risque dans des labs guidés en navigateur. Apprenez à repérer la vérification manquante, puis allez écrire celle qui l'arrête.