Aller au contenu

Principe de moindre privilège : juste ce qu'il faut

Mise à jour :

Un compte administrateur compromis donne accès à tout le système. Un compte applicatif avec les droits minimaux ne donne accès qu’à son périmètre. Le principe de moindre privilège exige que chaque utilisateur, processus ou service ne dispose que des permissions strictement nécessaires à sa fonction, et pas une de plus.

En résumé : Chaque entité (utilisateur, service, application) ne doit avoir que les droits indispensables à sa tâche. Les privilèges excessifs amplifient l’impact de toute compromission.

L’erreur des droits par facilité

Accorder des droits élevés “pour que ça marche” est une pratique courante et dangereuse.

Exemples de raisonnements dangereux :

  • “Je mets 777 pour éviter les problèmes de permissions”
  • “On donne sudo sans restriction, c’est plus simple”
  • “L’application tourne en root, comme ça elle a accès à tout”
  • “Tous les développeurs sont admins sur les serveurs de dev”
  • “Ce compte de service a les droits DBA, au cas où”

Chaque privilège excessif représente :

  • Un périmètre d’impact élargi en cas de compromission
  • Une possibilité d’erreur humaine aux conséquences amplifiées
  • Une violation de conformité (PCI-DSS, ISO 27001, SOC2)
  • Un obstacle au forensic (qui a fait quoi ?)

Le principe de moindre privilège

Le moindre privilège s’applique à tous les niveaux d’un système :

NiveauApplication
UtilisateursComptes nominatifs avec rôles restreints
ApplicationsExécution sous compte dédié non privilégié
Services systèmeDroits limités au strict nécessaire (systemd, capabilities)
ConteneursNon-root, capabilities restreintes, seccomp
Base de donnéesUtilisateurs applicatifs avec droits sur leurs tables uniquement
Cloud (IAM)Politiques avec permissions minimales, pas de *:*

La métaphore du badge d’accès

Dans une entreprise sécurisée, chaque employé a un badge qui ouvre uniquement les portes nécessaires à son travail. Le comptable accède à la comptabilité, pas au datacenter. L’agent d’entretien accède aux locaux techniques, pas aux bureaux de direction.

Un système informatique suit la même logique : chaque identité (humaine ou machine) ne doit pouvoir accéder qu’aux ressources requises pour sa mission.

Les mécanismes de mise en œuvre

Comptes utilisateurs Linux

Les systèmes Unix/Linux offrent plusieurs mécanismes pour appliquer le moindre privilège.

Utilisateurs et groupes :

  • Un compte par personne (jamais de comptes partagés)
  • Groupes fonctionnels pour les accès partagés
  • Pas de connexion directe en root (utiliser sudo)

Gestion de sudo :

Terminal window
# Mauvais : accès total
user ALL=(ALL) ALL
# Mieux : commandes spécifiques
user ALL=(ALL) /usr/bin/systemctl restart nginx
user ALL=(ALL) /usr/bin/journalctl -u nginx
# Encore mieux : avec justification et timeout
Defaults timestamp_timeout=5
Defaults log_input, log_output

Services système

Un service ne devrait jamais tourner en root sauf nécessité absolue.

Avec systemd :

[Service]
User=appuser
Group=appgroup
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
CapabilityBoundingSet=CAP_NET_BIND_SERVICE

Ces directives :

  • Exécutent le service sous un utilisateur dédié
  • Empêchent l’acquisition de nouveaux privilèges
  • Isolent le système de fichiers
  • Limitent les capabilities Linux au strict nécessaire

Conteneurs

Les conteneurs par défaut héritent souvent de trop de privilèges.

Bonnes pratiques :

  • Exécuter en non-root (USER 1000 dans le Dockerfile)
  • Supprimer toutes les capabilities (--cap-drop=all)
  • Ajouter uniquement celles nécessaires (--cap-add=NET_BIND_SERVICE)
  • Utiliser les profils seccomp et AppArmor/SELinux
  • Éviter --privileged sauf cas exceptionnels documentés

Bases de données

Chaque application devrait avoir son propre utilisateur base de données avec des droits limités à ses tables.

Anti-patternBonne pratique
Application connectée en rootUtilisateur dédié par application
Droits GRANT ALLDroits SELECT, INSERT, UPDATE sur tables spécifiques
Un seul compte pour dev/prodComptes séparés par environnement
Mots de passe dans le codeSecrets managés (Vault, Secret Manager)

Cloud IAM

Les politiques IAM cloud sont souvent trop permissives par défaut.

Principes à appliquer :

  • Jamais de "Action": "*" ou "Resource": "*"
  • Utiliser les managed policies les plus restrictives
  • Préférer les rôles assumables aux credentials long-terme
  • Activer les Service Control Policies (SCP) pour les guardrails
  • Auditer régulièrement avec des outils comme AWS IAM Access Analyzer

Scénario 1 : Le compte de service tout-puissant

Une application web est déployée avec un compte de service ayant tous les droits sur le serveur.

Configuration initiale :

  • Application exécutée en root
  • Accès sudo sans restriction
  • Connexion base de données en DBA
  • Clé SSH avec accès à tous les serveurs

Attaque :

  1. L’attaquant exploite une vulnérabilité applicative (injection)
  2. Il obtient une exécution de code sous le compte root
  3. Il accède à toutes les bases de données (droits DBA)
  4. Il pivote vers tous les serveurs (clé SSH partagée)
  5. Compromission totale de l’infrastructure

Avec moindre privilège :

  • Application sous compte dédié appweb
  • Aucun sudo, capabilities minimales
  • Base de données : droits SELECT/INSERT sur 3 tables
  • Pas de clé SSH (déploiement via CI/CD)

Même attaque :

  1. L’attaquant exploite la même vulnérabilité
  2. Il obtient un accès limité au compte appweb
  3. Il ne peut lire que les données de l’application
  4. Il ne peut pas pivoter (pas de credentials)
  5. Impact contenu à une seule application

Scénario 2 : Le développeur admin

Tous les développeurs ont des accès administrateur sur les environnements de développement “pour aller plus vite”.

Situation initiale :

  • 15 développeurs avec sudo complet
  • Accès direct aux serveurs par clé SSH personnelle
  • Pas de traçabilité des actions

Incident :

  1. Un développeur supprime accidentellement un répertoire critique
  2. Impossible de savoir qui a fait l’action
  3. Les backups datent de 24h, perte de données
  4. Aucune procédure de restauration testée

Avec moindre privilège :

  • Développeurs avec accès limité aux logs et redémarrage services
  • Actions privilégiées via pipeline CI/CD avec validation
  • Toutes les actions sudo journalisées

Même erreur :

  1. Le développeur tente de supprimer le répertoire
  2. Permission refusée (pas les droits)
  3. S’il avait les droits (via procédure), l’action est tracée
  4. Restauration possible, responsabilité identifiable

Comment implémenter le moindre privilège

Inventaire des accès

Commencez par cartographier l’existant :

  • Qui a accès à quoi ? Liste des utilisateurs et leurs droits
  • Quels services tournent avec quels droits ? Audit systemd/supervisor
  • Quelles credentials existent ? Clés SSH, tokens, mots de passe
  • Qui utilise vraiment ces accès ? Logs d’authentification

Définition des rôles

Créez une matrice de rôles basée sur les fonctions réelles :

RôleServeursActionsDonnées
DéveloppeurDev uniquementLogs, restartDonnées test
OpsTousMonitoring, restartMétadonnées
DBABases de donnéesBackup, maintenanceDonnées prod
AdminTousToutesToutes

Révocation et rotation

Les droits doivent être régulièrement révisés :

  • Révocation automatique des accès des personnes qui quittent l’équipe
  • Revue trimestrielle des droits accordés
  • Expiration automatique des accès temporaires
  • Rotation des secrets (mots de passe, clés, tokens)

Pièges courants

Le moindre privilège théorique

Définir des politiques strictes mais accorder des exceptions permanentes “en attendant”. Ces exceptions deviennent la norme.

L’accumulation de droits

Au fil des projets, un utilisateur accumule des droits sans jamais en perdre. En 3 ans, il a accès à tout sans en avoir besoin.

Le contournement par les secrets

Appliquer le moindre privilège sur les comptes mais laisser traîner des credentials partagées dans des wikis ou des scripts.

L’oubli des comptes de service

Se concentrer sur les utilisateurs humains et oublier que les applications et services ont aussi besoin d’être restreints.

À retenir

  1. Juste ce qu’il faut, pas plus — chaque droit excessif amplifie l’impact d’une compromission.

  2. Aucun compte ne devrait être permanent sans justification — les accès doivent être régulièrement révisés.

  3. Les services ne doivent jamais tourner en root — sauf nécessité absolue et documentée.

  4. Tracer toutes les actions privilégiées — pour la conformité et le forensic.

  5. Séparer les environnements — dev, test et production doivent avoir des credentials distincts.

  6. Automatiser la révocation — les accès temporaires doivent expirer automatiquement.

Liens utiles