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 editor peut publier des articles. Un utilisateur avec le rôle viewer peut 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/1234 retourne 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/users est 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 role dans 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)