Après la RLS, c'est la faille que je trouve le plus souvent. Un client lit, ou modifie, les données d'un autre, juste en changeant un identifiant dans une URL. Pas de "hack", pas d'exploit compliqué. Et pourtant c'est classé risque numéro un des applications web depuis des années. Voici comment ça marche, et comment l'éviter sur ton SaaS.
C'est quoi un IDOR
IDOR veut dire Insecure Direct Object Reference, on dit aussi BOLA. Le principe : tu exposes un objet par son identifiant, par exemple /api/factures/123. Si ton serveur te renvoie la facture 123 sans vérifier qu'elle t'appartient, il suffit de remplacer 123 par 124 pour voir la facture de quelqu'un d'autre. Même chose en modifiant un identifiant dans le corps d'une requête.
Pourquoi c'est la faille numéro un
Trois raisons. Elle passe la relecture de code, parce que le code "marche" du point de vue de l'utilisateur normal. Aucun outil automatique ne la détecte, parce qu'il faut deux comptes et un humain qui essaie. Et elle fuite exactement ce qui fait mal : les données des autres clients. C'est pour ça que je la teste systématiquement.
Comment l'éviter
1. Vérifie la propriété à chaque accès
Chaque lecture et chaque écriture d'un objet doit prouver, côté serveur, que l'objet appartient à l'utilisateur connecté. Et pas avec un contrôle "après coup" qu'on oublie une fois sur deux : directement dans la requête.
-- bien : la propriété est dans la requête
select * from factures where id = $1 and user_id = auth.uid();
-- fragile : on récupère d'abord, on vérifie "peut-être" ensuite
-- select * from factures where id = $1; // puis un if optionnel
2. Renvoie 404, pas 403
Quand un utilisateur demande un objet qui n'est pas à lui, réponds 404, pas 403. Un 403 confirme que l'objet existe, ce qui aide déjà un attaquant à cartographier tes données. Le 404 ne révèle rien.
3. Utilise des identifiants non devinables
Un identifiant auto-incrémenté (1, 2, 3...) sur une ressource sensible, c'est une invitation à énumérer. Préfère des UUID ou des ULID. Ce n'est pas une protection à soi seul, le contrôle d'accès reste obligatoire, mais ça retire le côté "je change juste le numéro".
4. Vérifie chaque niveau des ressources imbriquées
Sur une URL comme /projets/{a}/fichiers/{f}, vérifie à la fois que le fichier f appartient au projet a, et que le projet a appartient à l'utilisateur. Un seul maillon non vérifié, et la chaîne casse.
Le test qui trouve le plus de vraies failles : deux navigateurs, deux comptes, et tu rejoues les requêtes de l'un en te faisant passer pour l'autre.
Comment tester en dix minutes
- Ouvre deux comptes, A et B, dans deux navigateurs.
- Depuis le compte A, rejoue chaque appel du compte B en remplaçant les identifiants par ceux de B.
- Tout
200qui renvoie les données de B est une faille. Et lis toujours le corps de la réponse, pas seulement le code HTTP.
Un client peut-il voir les données d'un autre chez toi ?
C'est précisément ce que je teste en audit, compte contre compte, sur tout ton SaaS. Commence par le scan gratuit pour voir ta surface, ou passe à l'audit pour le fond.
Scanner mon SaaS, gratuitQuestions fréquentes
C'est quoi un IDOR ?
Une faille de contrôle d'accès où, en changeant un identifiant dans une URL ou une requête, un utilisateur accède à l'objet d'un autre utilisateur.
Un IDOR est-il grave ?
Oui, c'est du Broken Access Control, le risque numéro un des applications web, et il expose les données de tes autres clients.
À lire aussi : sécuriser la RLS Supabase et les failles de webhook Stripe.
← Retour au blog