Contrôle d'accès cassé : falsifier le rôle admin via un paramètre côté client
Le défi
Voici la requête que l'app envoie pour charger votre panneau de compte. Remarquez qu'elle indique au serveur votre propre rôle, juste là dans la requête. Le serveur l'a cru. Changez le rôle, envoyez, et lisez la note réservée aux admins que la réponse laisse fuiter.
Ce que tu vas apprendre
- Reconnaître un contrôle d'accès cassé quand le serveur lit le rôle d'un utilisateur depuis un paramètre de requête plutôt que depuis la session authentifiée
- Comprendre comment modifier un champ de privilège contrôlé par le client mène à une élévation de privilèges verticale
- Identifier quelles parties d'une requête HTTP sont contrôlées par l'attaquant et donc non fiables comme donnée d'autorisation
- Expliquer pourquoi les décisions d'autorisation doivent être dérivées côté serveur à partir de la session, jamais renvoyées depuis une entrée client
- Relier ce schéma à des problèmes connexes comme les références directes non sécurisées à un objet et le mass assignment
Compétences testées
Prérequis
- Compréhension de base des requêtes HTTP, des paramètres de requête et des cookies
- Familiarité avec la notion de rôles utilisateur et de niveaux d'accès (client, support, admin)
Comment ça marche
Le contrôle d'accès cassé est l'incapacité à faire respecter ce qu'un utilisateur authentifié est réellement autorisé à faire. C'est systématiquement l'une des classes de vulnérabilités web les plus courantes et les plus dommageables. Dans ce challenge, l'application demande au serveur de charger un panneau de compte, et elle place le rôle de l'utilisateur directement dans la requête sous forme de paramètre de requête. Le serveur lit ce paramètre et l'utilise pour décider quels panneaux et quelles données renvoyer : il traite une valeur contrôlée par l'utilisateur comme la source de vérité pour l'autorisation.
C'est un cas d'école d'élévation de privilèges. Un rôle est une décision d'autorisation, pas une donnée saisie par l'utilisateur. Quand le serveur fait confiance à un rôle, un champ de support ou de privilège défini côté client, n'importe quel utilisateur peut simplement le réécrire pour revendiquer un niveau supérieur. La requête transite par le navigateur et par tout proxy que l'utilisateur exécute, donc chaque octet de l'URL, des en-têtes et des cookies est contrôlé par l'attaquant. Renvoyer cette valeur dans une décision d'accès revient à mettre le verrou du mauvais côté de la porte.
La même cause profonde apparaît sous plusieurs noms : élévation de privilèges verticale quand un utilisateur peu privilégié obtient un rôle supérieur, référence directe non sécurisée à un objet quand un identifiant pointe vers une ressource qui devrait être inaccessible, et mass assignment quand une requête définit discrètement un champ comme is_admin que l'utilisateur n'était jamais censé pouvoir modifier. Dans tous les cas, la correction repose sur la même idée : le serveur doit déduire l'autorité de la session authentifiée, jamais des données que le client peut modifier.
Erreurs fréquentes
- Supposer que le rôle affiché dans la requête est fixé par le serveur, alors que ce n'est que du texte dans une URL que n'importe qui peut réécrire avant de l'envoyer.
- Essayer d'abord des payloads d'injection obscurs au lieu de lire la requête et de remarquer qu'une valeur d'autorisation est là, en clair, entièrement modifiable.
- Se précipiter vers le palier au nom le plus impressionnant sans lire les réponses : l'option la plus haute ici est rejetée car elle exige un second facteur, c'est donc une impasse.
- Traiter le bug comme une mauvaise valeur de paramètre plutôt que comme la vraie faille : le serveur n'aurait jamais dû accepter un rôle venant du client.
Comment s'en protéger
Ne lisez jamais le rôle, le niveau de permission ou tout attribut d'autorisation d'un utilisateur depuis un paramètre de requête, un cookie, un champ de formulaire caché ou un corps de requête. Récupérez l'identité de l'appelant depuis la session authentifiée côté serveur, allez chercher son rôle dans votre magasin de confiance, et appliquez-le à cet endroit. La requête doit décrire ce que l'utilisateur veut faire, jamais ce qu'il est autorisé à faire.
- Résolvez le rôle depuis la session côté serveur, puis vérifiez-le par rapport à l'action demandée avec une politique de refus par défaut.
- Ignorez et ne faites jamais confiance à un champ de rôle, de permission ou de privilège fourni par le client : ignorez-le plutôt que de l'honorer.
- Appliquez des contrôles d'accès au niveau objet et au niveau fonction sur chaque endpoint, y compris ceux que l'interface n'expose pas, car les attaquants appellent directement l'API.
- Enregistrez et déclenchez une alerte quand une requête tente de revendiquer un rôle supérieur à celui de la session, afin que l'abus soit visible.