Chacun des trois grands fournisseurs propose un interrupteur situé au-dessus du bucket individuel, qui écrase toute configuration faite en dessous. Votre après-midi comporte deux tâches : trouver ce qui est déjà ouvert, puis activer ces interrupteurs pour que la prochaine politique négligente reste sans effet. Respectez cet ordre, car ces interrupteurs casseront tout ce qui repose sur un accès public.
Ce que "public" signifie sur chaque plateforme
Les définitions diffèrent, et l'audit doit rechercher chacune d'elles.
| Plateforme | Ce qui rend l'accès public | Garde-fou qui l'écrase |
|---|---|---|
| AWS S3 | ACL accordant l'accès aux groupes AllUsers ou AuthenticatedUsers, ou bucket policy dont le caractère non public n'est pas démontrable | Block Public Access, au niveau du compte ou de l'organisation |
| Azure Blob | Le compte autorise l'accès anonyme et le niveau du conteneur est défini sur Container ou Blob | AllowBlobPublicAccess défini sur False sur le compte de stockage |
| Google Cloud Storage | allUsers ou allAuthenticatedUsers dans une politique IAM de bucket ou une ACL d'objet | Public access prevention, par bucket ou via la contrainte storage.publicAccessPrevention |
S3 considère une bucket policy comme publique tant que l'inverse n'est pas prouvé. Elle n'est jugée non publique que si elle accorde l'accès à des valeurs fixes, sans caractères génériques ni variables de politique, par exemple un principal précis ou un ensemble de blocs CIDR via aws:SourceIp. Un principal générique échoue donc au test.
Sur Azure, les deux conditions doivent être réunies. Si le compte interdit l'accès anonyme, le paramètre du conteneur n'a aucune importance. Si le compte l'autorise, un conteneur reste privé tant que son niveau n'est pas défini sur Container ou Blob.
Étape 1 : trouver ce qui est ouvert
S3. Le guide AWS recommande IAM Access Analyzer for S3 pour examiner les buckets publics, commencez donc par là. Vérifiez ensuite les quatre paramètres Block Public Access de chaque compte : BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy et RestrictPublicBuckets. Notez que GetBucketAcl renvoie les permissions effectives. Un bucket doté d'une ACL publique et dont IgnorePublicAcls est activé affichera une ACL qui masque la véritable.
Azure. Le portail vous donne d'abord le nombre de requêtes anonymes. Dans le compte de stockage, ouvrez Monitoring, puis Metrics. Utilisez le namespace Blob, la métrique Transactions, l'agrégation Sum, et ajoutez un filtre avec Authentication égal à Anonymous.
Pour savoir quels conteneurs sont concernés, créez un paramètre de diagnostic qui envoie les logs vers un workspace Log Analytics. Exécutez ensuite cette requête, qui couvre les sept derniers jours :
StorageBlobLogs
| where TimeGenerated > ago(7d) and AuthenticationType == "Anonymous"
| project TimeGenerated, AccountName, AuthenticationType, Uri
La colonne Uri nomme les conteneurs et les blobs lus. Les métriques et les logs montrent uniquement qui lit de façon anonyme, pas ce qui est exposé : un conteneur ouvert que personne n'a sollicité reste donc invisible. Vérifiez aussi les niveaux d'accès des conteneurs.
Google Cloud. Inspectez les politiques IAM des buckets à la recherche de rôles accordés à allUsers ou allAuthenticatedUsers. Cloud Asset Inventory affiche les politiques de tous les buckets d'un projet, d'un dossier ou d'une organisation, ce qui vous évite de procéder bucket par bucket. Les ACL d'objets demandent un examen séparé, et les managed folders ont leurs propres politiques IAM. Activez les usage logs pour voir quelles charges de travail touchent des données publiques. Cloud Audit Logs ne trace pas les accès aux objets publics, il ne vous sera donc d'aucune aide ici.
Étape 2 : activer les garde-fous
S3. AWS recommande d'activer les quatre paramètres au niveau du compte. Il recommande aussi les quatre sur chaque bucket pour satisfaire le contrôle Security Hub S3.8. Pour plusieurs comptes, utilisez une politique au niveau de l'organisation. Cette politique est tout ou rien, sans choix paramètre par paramètre, et elle écrase les réglages de niveau compte dans les comptes membres sélectionnés. S3 applique la combinaison la plus restrictive entre les niveaux : un bucket ne peut donc pas affaiblir ce que le compte impose.
Appliquez en particulier BlockPublicPolicy au niveau du compte. Sinon, toute personne pouvant modifier une bucket policy peut insérer une politique qui désactive le paramètre au niveau du bucket. Les changements au niveau du compte s'appliquent à toutes les Regions, mais pas forcément partout au même moment. Les paramètres des access points ne peuvent être définis qu'à la création, vérifiez-les donc séparément.
Azure. Définissez AllowBlobPublicAccess sur False sur chaque compte de stockage. Cela écrase tous les paramètres des conteneurs, vous n'avez donc pas besoin d'y toucher. Cela exige la version 2019-04-01 ou ultérieure du resource provider Azure Storage. L'utilisateur doit disposer de Microsoft.Storage/storageAccounts/write, que comprennent les rôles Owner, Contributor et Storage Account Contributor. Limitez strictement ces attributions.
Google Cloud. Appliquez Public access prevention sur les buckets, ou définissez la contrainte de politique d'organisation storage.publicAccessPrevention au niveau du projet, du dossier ou de l'organisation. Google conseille d'appliquer la contrainte au niveau le plus haut possible. L'état d'un bucket est soit enforced, soit inherited. Un bucket dont le réglage est enforced le reste, même si vous désactivez ensuite la contrainte située au-dessus.
Ce qui va casser, et ce qui ne cassera pas
Prévoyez des casses, car c'est précisément le but de l'exercice.
- S3 : les paramètres ne modifient ni les politiques ni les ACL existantes. Retirer un paramètre rend de nouveau public tout ce qui a une politique ou une ACL publique : nettoyez donc aussi les autorisations sous-jacentes. Examinez également les politiques basées sur l'identité et les politiques de ressources comme les key policies KMS, que Block Public Access ne couvre pas.
- Azure : les lectures anonymes se mettent à échouer. Le code dépend de la version du service : 401 pour les versions 2019-12-12 et ultérieures, sinon 409 lorsque le compte interdit l'accès anonyme et 404 lorsqu'il l'autorise.
- Google Cloud : les requêtes utilisant
allUserséchouent avec un HTTP 401 ou 403. Les bindings existants restent en place mais sont écrasés. Les tentatives d'en ajouter échouent avec412 Precondition Failed. Les signed URLs ne sont pas affectées. L'application peut prendre jusqu'à 10 minutes, et les objets en cache peuvent rester publics pendant la durée de vie définie parCache-Control, soit 3600 secondes par défaut.
Un contenu réellement public, comme un site web statique, nécessite une exception. Azure conseille de le déplacer vers un compte de stockage distinct, réservé à l'accès anonyme. Sur Google Cloud, désactivez la prévention sur le projet précis qui contient le bucket. Sur S3, personnalisez les paramètres individuels des buckets concernés.
Par où commencer
- Listez chaque compte AWS, abonnement Azure et projet Google Cloud qui contient du stockage, y compris ceux dont personne ne se souvient de la création.
- Lancez la découverte décrite plus haut : Access Analyzer for S3, la métrique de requêtes anonymes et la requête de logs Azure, et Cloud Asset Inventory pour les politiques IAM des buckets.
- Pour chaque résultat public, déterminez s'il est volontaire. Déplacez les contenus publics légitimes vers des comptes ou projets dédiés.
- Activez les contrôles au niveau du compte ou de l'organisation : les quatre paramètres S3,
AllowBlobPublicAccessdéfini sur False, et la contraintestorage.publicAccessPrevention. - Relancez les requêtes quelques jours plus tard pour confirmer que les requêtes anonymes sont tombées à zéro, et configurez une alerte sur la métrique de requêtes anonymes d'Azure.
- Si vous souhaitez une vérification externe de ce qui reste accessible, notre service de test d'intrusion couvre l'exposition cloud, et notre équipe de conseil peut examiner la structure de vos comptes.
