Arkendia Classrooms
Leçon 17 sur 28 · 15 min

IDOR : les références directes non sécurisées

Jusqu’ici, nous avons surtout cherché des failles dans le traitement des données. Entrons dans une famille de problèmes plus discrète, et pourtant l’une des plus répandues : l’application ne vérifie pas que vous avez le droit d’accéder à ce que vous demandez. Elle sait qui vous êtes (authentification), mais oublie de contrôler ce que vous pouvez faire (autorisation). Le cas le plus emblématique s’appelle l’IDOR : Insecure Direct Object Reference.

Rappel légal et éthique

Consulter les données d’une autre personne en changeant un numéro dans une adresse peut sembler anodin, mais sur un site réel, c’est un accès frauduleux à des données (articles 323-1 à 323-3-1 du Code pénal) et souvent une atteinte à la vie privée, même si « il suffisait de changer un chiffre ». Un chercheur légitime s’arrête dès qu’il a prouvé la faille et ne consulte pas les données réelles d’autrui. Ici, vous opérez avec deux comptes de test à vous dans OWASP Juice Shop, DVWA ou un laboratoire de la PortSwigger Web Security Academy.

Le principe

Une application utilise souvent des identifiants pour désigner les objets qu’elle manipule : numéro de commande, identifiant de profil, nom de fichier, numéro de facture. Ces références apparaissent dans les adresses ou les requêtes :

GET /factures?id=1042
GET /api/profils/317
POST /commande/annuler  (corps : commande=5521)

Il y a IDOR quand l’application utilise la référence fournie par l’utilisateur pour retrouver l’objet, sans vérifier que cet objet appartient bien à l’utilisateur connecté. Il suffit alors de changer le numéro pour accéder à un autre objet.

Analogie : un vestiaire où l’on vous remet un jeton numéroté. Si le préposé rend n’importe quel manteau à quiconque présente un numéro valide, sans vérifier que c’est bien le vôtre, il suffit d’essayer un autre numéro. Le numéro est une référence, pas une preuve de propriété.

Pourquoi cette faille est si courante

  • Elle est invisible à l’usage normal : tant que chacun clique sur ses propres liens, tout fonctionne.
  • Elle ne se détecte pas par un scanner automatique de façon fiable : un outil ne sait pas, seul, à qui appartient une donnée. Il faut un test manuel avec plusieurs comptes.
  • Elle résulte souvent d’un oubli : le développeur contrôle l’accès sur les pages principales, mais pas sur une fonction annexe, une API ou un export.

Cette catégorie de risque occupe une place très haute dans le Top 10 de l’OWASP, sous l’intitulé du contrôle d’accès défaillant.

Où chercher des références

Votre carte de l’application (chapitre 1) est ici précieuse. Parcourez-la et repérez tout ce qui ressemble à un identifiant d’objet :

EmplacementExemple
Dans le chemin de l’adresse/commandes/5521
Dans un paramètre d’adresse?utilisateur=317
Dans le corps d’une requête{"panier": 88}
Dans un champ masqué de formulaire<input type="hidden" name="compte" value="317">
Dans un nom de fichier/documents/facture_1042.pdf
Dans un en-tête ou un cookieX-Compte: 317

Les API REST sont particulièrement concernées : elles exposent des identifiants partout et sont parfois moins surveillées que l’interface web.

La démarche de test à deux comptes

La méthode fiable consiste à comparer ce que voient deux utilisateurs distincts. Dans votre application d’entraînement :

  1. Créer deux comptes de test, A et B, avec des données distinctes (une commande ou un panier pour chacun).
  2. Avec A, accomplir une action et capturer la requête dans le proxy : notez la référence à votre objet (par exemple l’identifiant de votre panier).
  3. Avec B, faire de même et noter sa propre référence.
  4. Rejouer la requête de A en remplaçant la référence par celle de B, tout en conservant le cookie de session de A.
  5. Observer : si l’application renvoie les données de B à A, il y a IDOR. Si elle répond par un refus (erreur d’accès interdit), le contrôle existe.

Votre preuve repose donc sur vos propres données : vous démontrez l’accès non autorisé entre deux comptes qui vous appartiennent, sans jamais toucher à des données de tiers. C’est la bonne façon de procéder dans un audit : si le client vous a fourni deux comptes de test, vous utilisez ceux-là.

Les identifiants « imprévisibles » ne sont pas une protection

Remplacer un numéro séquentiel par un identifiant long et aléatoire rend les références difficiles à deviner, ce qui est un bon réflexe de défense en profondeur. Mais cela ne règle pas la faille : si l’identifiant fuit (dans un lien partagé, un journal, une autre réponse de l’API), il suffit à accéder à l’objet. La vraie correction est la vérification d’autorisation côté serveur.

Lecture, modification, suppression

Testez chaque méthode, pas seulement la lecture. Une application peut protéger la consultation d’une commande (GET) mais laisser n’importe qui la modifier (PUT) ou l’annuler (DELETE). Notez, pour chaque objet, quelles opérations sont contrôlées.

Les défenses

  • Vérifier l’autorisation à chaque accès, côté serveur : « cet objet appartient-il à l’utilisateur connecté, ou celui-ci a-t-il un droit explicite dessus ? ». Le contrôle doit être appliqué de façon systématique, idéalement dans une couche centrale, pas page par page.
  • Dériver l’identité de la session, pas de la requête : pour afficher « mes commandes », le serveur utilise l’utilisateur de la session, pas un paramètre utilisateur=… envoyé par le client.
  • Refuser par défaut : un accès n’est possible que s’il est explicitement autorisé.
  • Utiliser des identifiants non devinables en complément.
  • Journaliser et surveiller les accès refusés répétés, signe d’un balayage.
// Mauvais : l'objet est retrouvé sans vérifier son propriétaire
$commande = $pdo->query("SELECT * FROM commandes WHERE id = " . (int)$_GET['id'])->fetch();

// Meilleur : la requête inclut l'utilisateur de la session
$stmt = $pdo->prepare("SELECT * FROM commandes WHERE id = :id AND utilisateur_id = :uid");
$stmt->execute([':id' => (int)$_GET['id'], ':uid' => $_SESSION['utilisateur_id']]);
$commande = $stmt->fetch();
if (!$commande) { http_response_code(404); exit; }

Notez que la version corrigée répond « introuvable » plutôt que « interdit » : cela évite de confirmer l’existence de l’objet à quelqu’un qui n’y a pas droit.

Astuce

Dans le carnet, tenez un tableau « objet × utilisateur × opération » avec le résultat attendu et le résultat observé. Les écarts sont vos constats, et le tableau lui-même prouve l’exhaustivité de votre test.

À vous de jouer

  1. Dans OWASP Juice Shop, créez deux comptes (A et B) et ajoutez un article au panier de chacun. Avec le proxy, capturez la requête qui consulte le panier de A.
  2. Identifiez la référence au panier dans la requête. Quelle autre information la requête contient-elle pour identifier l’utilisateur ?
  3. Réfléchissez à la question suivante : comment vérifieriez-vous, avec vos deux comptes, que l’application contrôle bien que le panier appartient à l’utilisateur connecté ? Écrivez le protocole de test.
  4. Consignez dans votre carnet le résultat de votre test, même s’il est négatif (« le contrôle existe »).
Voir une solution

La requête contient généralement une référence au panier (un numéro) et un jeton ou cookie identifiant la session de A. Protocole : (1) capturer la requête de A pour son panier ; (2) noter la référence au panier de B ; (3) rejouer la requête de A en remplaçant la référence par celle de B, avec la session de A ; (4) observer : refus ou données de B. Résultat consigné : « Test IDOR sur la consultation du panier : [accès refusé / données de l’autre compte renvoyées]. » Si l’application d’entraînement est volontairement vulnérable, c’est un défi connu : le constat contiendra la preuve, la gravité (accès aux données d’un autre utilisateur) et la correction (vérifier la propriété côté serveur).

À retenir

  • L’IDOR survient quand une référence d’objet fournie par l’utilisateur est acceptée sans contrôle de propriété.
  • Un scanner automatique le détecte mal : on teste manuellement avec deux comptes de test.
  • Testez toutes les opérations (lecture, modification, suppression), pas seulement l’affichage.
  • Des identifiants imprévisibles aident, mais la vraie défense est l’autorisation côté serveur à chaque accès.
  • N’accédez jamais aux données réelles d’autrui : prouvez avec vos propres comptes.

L’IDOR illustre un cas particulier d’une famille plus large : les élévations de privilèges, objet de la leçon suivante.

Publicité
Connectez-vous pour enregistrer votre progression. Se connecter