Contrôle d'accès
Rappel : autorisation ≠ authentification
L’autorisation répond à la question qu’as-tu le droit de faire ? Elle intervient après l’authentification. Être connecté ne suffit pas : encore faut-il avoir la permission d’accéder à une ressource ou d’exécuter une action.
Modèles d’autorisation
ACL (Access Control List) est le mécanisme primitif : une liste de qui peut faire quoi, attachée directement à chaque ressource. Les modèles ci-dessous (RBAC, ABAC, ReBAC) sont des abstractions construites pour dépasser ses limites à l’échelle.
RBAC — Role-Based Access Control
Les permissions sont attachées à des rôles, et les rôles sont assignés aux utilisateurs.
Exemple : un utilisateur avec le rôle
editorpeut publier des articles. Un utilisateur avec le rôleviewerpeut seulement les lire.
- Simple à comprendre et à administrer
- Adapté quand les groupes d’utilisateurs sont bien définis
- Limite : peu flexible pour des règles contextuelles (“un editor ne peut modifier que ses propres articles”)
ABAC — Attribute-Based Access Control
Les permissions sont évaluées à partir d’attributs : ceux de l’utilisateur, de la ressource, et du contexte.
Exemple : un médecin peut accéder au dossier d’un patient uniquement s’il est assigné à ce patient et que la consultation est en cours.
- Très expressif et flexible
- Adapté aux règles métier complexes
- Plus difficile à auditer et à déboguer
ReBAC — Relationship-Based Access Control
Les permissions sont définies par les relations entre entités : utilisateur → ressource, ressource → ressource parente, utilisateur → utilisateur.
Exemple : tu as accès à un fichier parce qu’il est dans un dossier qui t’a été partagé. La permission se propage le long de la relation “contenu dans”. Tu n’as pas de rôle particulier — tu as une relation avec la ressource.
- La question n’est plus “quel rôle as-tu ?” mais “quelle relation as-tu avec cette ressource ?”
- Très adapté aux structures hiérarchiques et aux partages dynamiques entre utilisateurs
- Plus expressif que RBAC pour les cas multi-tenant et les ressources partagées à la volée
- Popularisé par le papier Google Zanzibar (2019) — implémentations open source : SpiceDB, OpenFGA
Principe du moindre privilège
Donner à chaque utilisateur (ou service) uniquement les permissions dont il a besoin, et rien de plus.
C’est le principe fondamental du contrôle d’accès. Il limite les dégâts en cas de compromission : un compte avec peu de droits ne peut pas faire beaucoup de mal.
En pratique :
- Ne pas donner un rôle admin par défaut
- Révoquer les accès inutilisés
- Préférer des permissions temporaires pour les opérations sensibles
Erreurs classiques
Vérification côté client uniquement
Cacher un bouton dans l’interface ne suffit pas. Si l’API derrière ne vérifie pas les permissions, n’importe qui peut appeler l’endpoint directement.
L’autorisation doit toujours être vérifiée côté serveur, pour chaque requête.
Broken Object Level Authorization (BOLA)
L’une des failles les plus répandues. L’utilisateur accède à une ressource qui ne lui appartient pas en changeant un identifiant dans la requête.
Exemple : l’URL
/api/orders/1234retourne la commande d’un autre utilisateur si le serveur ne vérifie pas que la commande appartient bien à l’utilisateur connecté.
Broken Function Level Authorization
Des fonctions sensibles (suppression, export, administration) sont accessibles sans vérification de rôle.
Exemple : l’endpoint
/api/admin/usersest appelable par n’importe quel utilisateur connecté si le contrôle de rôle est absent.
Escalade de privilèges
Un utilisateur modifie ses propres attributs (rôle, permissions) via une requête non protégée.
Exemple : un formulaire de mise à jour du profil accepte un champ
roledans le body JSON, permettant à l’utilisateur de s’octroyer des droits.
Bonnes pratiques
- Vérifier les permissions côté serveur, sur chaque endpoint
- Toujours vérifier que la ressource demandée appartient à l’utilisateur (BOLA)
- Appliquer le principe du moindre privilège par défaut
- Journaliser les accès refusés — ils révèlent souvent des tentatives d’intrusion
- Tester explicitement les scénarios d’accès non autorisé (pas seulement les cas nominaux)