Falsifier l'ID de la facture : walkthrough IDOR / Broken Object Level Authorization
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 ? Changez l'id, envoyez, et lisez la facture #1020.
Ce que tu vas apprendre
- Reconnaître une IDOR (référence directe non sécurisée) où l'id d'un enregistrement est accepté tel quel depuis la requête
- Distinguer l'authentification (qui vous êtes) de l'autorisation (ce que vous êtes autorisé à accéder)
- Falsifier un seul paramètre dans une requête HTTP capturée et la rejouer pour atteindre l'objet d'un autre utilisateur
- Lire une réponse HTTP/JSON pour confirmer que vous avez reçu un enregistrement qui n'est pas le vôtre
- Expliquer pourquoi une vérification de propriété par objet est le bon correctif, et non un renforcement de la connexion
Compétences testées
Prérequis
- Compréhension de base d'une requête HTTP (méthode, chemin, chaîne de requête, en-têtes, cookies)
- Connaissance du fonctionnement d'un cookie de session pour authentifier un utilisateur connecté
- Aisance à lire un petit corps de réponse JSON
Comment ça marche
Une référence directe non sécurisée (IDOR) se produit lorsqu'une application expose une référence à un objet interne - une ligne de base de données, un fichier, une facture - directement dans la requête, puis fait confiance à cette référence sans vérifier que l'appelant est autorisé à accéder à cet objet précis. Le cas classique est un id numérique dans une URL ou une chaîne de requête, comme /api/invoice?id=1019. Comme l'id est séquentiel et prévisible, un attaquant peut simplement le remplacer par une valeur voisine et demander l'enregistrement de quelqu'un d'autre.
Le point subtil, c'est que l'endpoint n'est pas non authentifié. Le serveur a bien validé le cookie de session, donc il sait quel utilisateur appelle. L'erreur, c'est qu'il s'arrête là : il ne pose jamais la seconde question - cette facture appartient-elle vraiment à l'utilisateur connecté ? Vérifier l'identité (authentification) n'est pas la même chose que vérifier la permission d'accès à un objet précis (autorisation). Quand cette vérification par objet est absente, la faille est aussi appelée broken object level authorization (BOLA), le risque numéro un du OWASP API Security Top 10.
Ce challenge modélise exactement cet écart. Vous avez en main une requête réelle, capturée, pour votre propre facture. L'id figure dans la requête sous forme de texte brut, modifiable, et rien dans le format de la réponse ne laisse penser que le serveur distingue vos enregistrements de ceux des autres - c'est précisément le signe que l'autorisation est court-circuitée.
Erreurs fréquentes
- Supposer qu'un login valide suffit. Beaucoup d'apprenants voient le cookie de session et concluent que l'endpoint est sûr. L'authentification prouve seulement qui appelle ; elle ne dit rien sur les objets que cet appelant peut lire.
- Modifier la mauvaise partie de la requête. Le chemin, l'hôte et le cookie doivent rester exactement tels que capturés. Seule la référence à l'objet, la valeur de l'id, doit changer, et seul ce champ est en jeu ici.
- S'arrêter à un 404 et abandonner. Une réponse « introuvable » signifie simplement que cet id n'existe pas ; c'est un retour d'information, pas un mur. Ajustez l'id vers une valeur susceptible d'être un enregistrement réel, voisin.
- Traiter l'IDOR comme un bug d'injection. Aucun caractère spécial, encodage ou payload n'est nécessaire. Vous remplacez un id légitime par un autre id légitime : la vulnérabilité est un contrôle d'accès manquant, pas une entrée non filtrée.
Comment s'en protéger
Le correctif consiste en une vérification de propriété au niveau de l'objet à chaque accès. Une fois la session authentifiée, le serveur doit confirmer que l'objet demandé appartient (ou est partagé avec) cet utilisateur avant de le renvoyer, par exemple en limitant la requête à l'appelant : SELECT * FROM invoice WHERE id = ? AND owner_user_id = :sessionUser. Si la ligne ne correspond pas, renvoyer 404 ou 403, jamais les données. Renforcer le flux de connexion ne change rien ici, puisque l'attaquant est déjà connecté.
- Imposer l'autorisation par objet côté serveur ; ne jamais se fier au fait que le client ne demande que les id qu'il « devrait » connaître.
- Préférer des identifiants imprévisibles (UUID) aux entiers séquentiels pour supprimer l'énumération facile, tout en gardant la vérification de propriété : l'obscurité seule n'est pas un contrôle d'accès.
- Journaliser et alerter sur les tentatives d'accès qui échouent à la vérification de propriété, en particulier les balayages séquentiels d'id.