Énumération d'utilisateurs : comment votre API révèle qui sont vos clients
Une fuite qui ne ressemble pas à une fuite
Aucune donnée n'est volée, aucune base n'est compromise. Pourtant, un concurrent ou un attaquant peut apprendre : quelles entreprises utilisent votre SaaS, combien de salariés elles gèrent, et quelles adresses email professionnelles existent chez chacune. C'est l'énumération, et elle passe sous le radar parce qu'elle n'exploite que des comportements « normaux » de votre API.
Pour un SaaS RH, c'est doublement sensible : la liste de vos clients est votre actif commercial, et la liste des salariés d'un client est le point de départ idéal d'une campagne de phishing ciblée (« votre bulletin de paie est disponible »).
Les 4 vecteurs classiques
Les messages d'erreur différenciés
Login : « mot de passe incorrect » vs « utilisateur inconnu ». Inscription : « cette adresse est déjà utilisée ». Invitation d'un collègue : « cet utilisateur appartient à une autre organisation ». Chaque message différencié est un oracle qui confirme ou infirme l'existence d'un compte.
Les IDs séquentiels
GET /api/companies/1847 répond 403, GET /api/companies/1848 répond 404. Le 403 dit « existe mais pas à vous », le 404 dit « n'existe pas ». En itérant, on compte vos clients — et votre croissance mois par mois si les IDs sont chronologiques. Utilisez des UUIDs, et répondez 404 dans les deux cas.
Les temps de réponse
Même avec des messages identiques, si la vérification d'un mot de passe (bcrypt, ~100 ms) n'a lieu que quand l'utilisateur existe, la différence de latence suffit. Effectuez un hash factice quand le compte n'existe pas.
Les endpoints annexes oubliés
Le login est souvent protégé, mais pas : la demande de reset de mot de passe, la vérification de disponibilité d'email à l'inscription, l'ajout d'un membre à une équipe, le champ de recherche d'utilisateurs. L'attaquant utilise le maillon le plus bavard.
Le rate limiting, condition nécessaire mais pas suffisante
Sans rate limiting, l'énumération se fait à des milliers de requêtes par minute. Mais un rate limiting par IP seule ne suffit plus : les attaquants tournent sur des milliers d'IPs résidentielles louées. Combinez :
Checklist
Notre audit API teste systématiquement ces vecteurs en conditions réelles — c'est souvent la première chose qu'un scanner automatique ne voit pas.
Pour aller plus loin
Articles liés
Trois analyses proches pour continuer la lecture sur la meme surface de risque.
Gestion des tokens JWT dans un SaaS RH : les pièges à éviter
Les JSON Web Tokens sont partout dans les SaaS modernes. Mais une mauvaise gestion de leur expiration et rotation peut compromettre toute votre application.
API Silae, PayFit, Lucca : où regarder la sécurité des intégrations
Les intégrations paie et RH créent souvent leur propre surface d'exposition : secrets, webhooks, mapping d'identité et journaux.
GraphQL : 5 attaques spécifiques que les scanners ratent
Les vulnérabilités propres à GraphQL que les outils automatisés ne détectent pas : introspection, batching, deep queries, aliases et injections.
Sources
Services associés
Si ce sujet reflète un risque concret sur votre stack, voici les audits CleanIssue les plus pertinents.