Sites.FullControl.All : la permission qui laisse un fournisseur refaire votre plan d'accès
Étude de cas : contenir une permission Graph qui ouvre la gouvernance SharePoint du tenant entier.
Le scénario
Une entreprise cotée en bourse, 2 000 employés, travaille sur une acquisition stratégique. Le comité M&A dispose d'un site SharePoint dédié, accès restreint par un groupe de sécurité limité à cinq personnes. Les documents sont étiquetés Restricted-MA.
Un ISV de gestion documentaire est déployé tenant-wide depuis 18 mois avec Sites.FullControl.All, pour synchroniser les politiques de rétention entre SharePoint et un système d'archivage externe. Classique.
Un développeur chez l'ISV se fait compromettre. L'attaquant utilise le jeton applicatif pour trois actions, dans cet ordre. Ajouter un utilisateur invité au site M&A, créé pour l'occasion. Télécharger les 14 Go de documents. Effacer l'utilisateur invité, puis modifier les colonnes d'audit du site pour retirer l'événement d'ajout.
L'audit unifié garde une trace au niveau tenant. Le site lui-même ne montre plus rien. L'équipe sécurité n'apprendra l'incident que trois semaines plus tard, quand l'acquisition fuit dans la presse et qu'il faut remonter à la source.
Pourquoi Microsoft ne bloque pas ce scénario
Sites.FullControl.All fait exactement ce que son nom promet : contrôle complet sur tous les sites. Modifier les permissions est une opération légitime pour une application de gouvernance documentaire. Microsoft ne peut pas distinguer une modification légitime d'une modification malveillante sans signal contextuel.
Le risque n'est pas l'exfiltration, qui serait détectée par Purview DLP. Le risque est le pivot : utiliser la permission de gouvernance pour s'accorder d'autres permissions, contourner les groupes, effacer les traces. Le blast radius de cette permission est tout le plan d'accès SharePoint du tenant.
Microsoft offre un mode préventif via Sites.Selected, qui force l'application à demander explicitement l'accès à chaque site. En pratique, les ISV de gouvernance documentaire ne l'adoptent pas parce que leur cas d'usage couvre tout le tenant par définition. L'alternative qui marche est d'interdire sélectivement les opérations à risque au niveau proxy. Le même raisonnement que pour Files.ReadWrite.All, transposé aux endpoints de gouvernance.
Ce que l'incident aurait donné avec un périmètre en place
Avec les appels SharePoint routés à travers un proxy de gouvernance, les règles suivantes s'appliquent. Modèle : default-deny. Tout appel non couvert par un allow explicite est bloqué.
Règle 1 — Lecture limitée au périmètre de l'application
- name: "Retention ISV — read scope"
endpoint_pattern: "/sites/*/drive/*"
http_methods: [GET]
conditions:
all_of:
- caller_identity:
application_id: "app-retention-isv"
- object_attribute:
path: "siteId"
not_in_tag: ["sensitive:confidential", "sensitive:m-and-a"]
action: allow
L'ISV de rétention n'a pas besoin de lire les sites M&A pour faire son travail. Les sites marqués sensitive dans l'annuaire sont structurellement hors de portée, même avec Full Control accordé côté Graph.
Règle 2 — Aucune modification de permissions
- name: "Retention ISV — no permission changes"
endpoint_pattern: "/sites/*/permissions/**"
http_methods: [POST, PATCH, DELETE]
conditions:
all_of:
- caller_identity:
application_id: "app-retention-isv"
action: block
Une application de gouvernance documentaire a besoin de lire les permissions pour son audit. Elle n'a pas besoin de les modifier. Bloquer explicitement les mutations sur /permissions retire la mécanique du pivot sans toucher à la fonctionnalité légitime.
Règle 3 — Colonnes d'audit protégées
- name: "Retention ISV — no audit column mutations"
endpoint_pattern: "/sites/*/lists/*/columns/*"
http_methods: [PATCH, DELETE]
conditions:
any_of:
- object_attribute:
path: "displayName"
matches_any: ["Audit*", "Modified*", "CreatedBy*", "Retention*"]
action: block
Modifier ou supprimer les colonnes de traçabilité était l'outil de nettoyage de l'attaquant. La règle protège la lignée d'audit structurellement : même l'application légitime ne peut pas effacer les traces, par design.
Règle 4 — Pas d'invités ajoutés par l'application
- name: "Retention ISV — no guest operations"
endpoint_pattern: "/sites/*/permissions"
http_methods: [POST]
conditions:
any_of:
- request_body:
path: "grantedToV2.user.@odata.type"
equals: "#microsoft.graph.guestUser"
action: block
L'ajout d'un utilisateur invité est un vecteur typique pour se donner soi-même accès à un site restreint. Aucune application de rétention n'a de raison métier de faire ça. La règle s'applique même aux opérations qui passeraient par des endpoints annexes : la condition est sur le corps de la requête, pas juste sur le chemin.
Règle 5 — Fenêtre opérationnelle
- name: "Retention ISV — scheduled maintenance windows"
endpoint_pattern: "/sites/*"
http_methods: [POST, PATCH, DELETE, PUT]
conditions:
all_of:
- time_window:
timezone: "America/Toronto"
days: ["Mon", "Tue", "Wed", "Thu"]
hours: "20:00-23:00"
action: allow
Les opérations de rétention suivent un cycle de maintenance la nuit, en semaine. Une écriture à 3h du matin le samedi est anormale et bloquée. Le signal temporel recouvre les angles morts des autres règles.
Les conditions sur request_body et object_attribute permettent une granularité qu'aucune permission Microsoft Graph n'expose nativement. Voir la documentation pour la grammaire complète.
Ce que ça change pour le décideur
Le pivot interne est le scénario que les équipes sécurité craignent sans pouvoir le modéliser facilement. L'application est légitime, le trafic est conforme, les données sortent par un chemin autorisé. Les outils de détection classiques (SIEM, DLP, audit unifié) voient l'activité mais ne la qualifient pas comme hostile.
Avec une couche de gouvernance, trois bascules.
- Le privilège descend au strict nécessaire. Full Control reste accordé, mais les opérations qui pivotent (permissions, colonnes d'audit, invités) deviennent inaccessibles à l'application.
- La lignée d'audit est intouchable. Les colonnes Audit sont protégées par règle, pas par convention. Aucune application, même compromise, ne peut les modifier.
- La réponse à incident est scriptée. Couper une app suspecte ne demande ni le fournisseur, ni Microsoft, ni un redéploiement : une règle
blockglobale parapplication_idet le trafic s'arrête.
Les limites qu'il faut nommer
Les règles reposent sur un tagging des sites (sensitive, m-and-a). Cela suppose un inventaire à jour, maintenu soit manuellement par l'équipe conformité, soit dérivé des Sensitivity Labels. Ce travail est rarement fait de façon systématique, et c'est souvent le premier chantier de gouvernance qui accompagne le déploiement d'une couche comme GraphWarden.
Deuxième limite : bloquer toutes les modifications de permissions par une application tue l'automatisation légitime (par exemple, un outil de self-service qui crée un site et ajoute son propriétaire). La granularité importe. Les règles ci-dessus ciblent un ISV de rétention précis, pas toutes les applications.
Ce qu'il faut retenir
Sites.FullControl.All est la permission qui concentre le plus de privilèges dans la surface SharePoint. Son risque ne se mesure pas en gigaoctets exfiltrés, mais en capacité de refaire votre plan d'accès sans que personne ne s'en aperçoive sur le moment.
Pour une organisation qui gère des transactions sensibles (fusions-acquisitions, contentieux, recherche, propriété intellectuelle), encadrer cette permission par des règles déclaratives est moins une option technique qu'un contrôle interne exigible par tout auditeur sérieux.
C'est exactement pour ça que GraphWarden existe.