Audit des Permissions des Buckets S3 AWS
Quand l'utiliser
- Lors d'une évaluation de sécurité d'environnements AWS pour identifier les données exposées publiquement
- Lors de l'intégration d'un nouveau compte AWS et de l'établissement d'une base de référence de sécurité pour les ressources de stockage
- En réponse à une alerte concernant une exposition potentielle de données S3 provenant d'AWS Trusted Advisor ou Security Hub
- Lorsque des cadres de conformité (SOC 2, PCI DSS, HIPAA) exigent une révision périodique des contrôles d'accès aux données
- Lorsqu'une violation ou un compromis d'identifiants nécessite un examen immédiat de toutes les ressources S3 accessibles
Ne pas utiliser pour auditer le stockage d'objets non-AWS (utiliser des outils spécifiques au fournisseur), pour la surveillance en temps réel (utiliser S3 Event Notifications avec Lambda), ou pour auditer les schémas d'accès S3 (utiliser S3 Access Analyzer ou CloudTrail S3 data events).
Prérequis
- AWS CLI v2 configuré avec des identifiants possédant les autorisations
s3:GetBucketPolicy,s3:GetBucketAcl,s3:GetBucketPublicAccessBlock,s3:GetEncryptionConfigurationets3:ListAllMyBuckets - Prowler installé (
pip install prowler) pour les vérifications automatisées du benchmark CIS - S3audit ou un outil d'énumération similaire pour la détection rapide des buckets publics
- Accès à AWS Organizations pour l'audit sur plusieurs comptes
- Python 3.8+ avec boto3 pour les scripts d'audit personnalisés
Workflow
Étape 1 : Énumérer tous les buckets S3 et le blocage d'accès public au niveau du compte
Vérifiez d'abord les paramètres de blocage d'accès public au niveau du compte, puis listez tous les buckets avec leurs régions.
# Vérifier les paramètres de blocage d'accès public au niveau du compte
aws s3control get-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--output json
# Lister tous les buckets avec les dates de création
aws s3api list-buckets \
--query 'Buckets[*].[Name,CreationDate]' \
--output table
# Obtenir les régions des buckets pour chaque bucket
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
region=$(aws s3api get-bucket-location --bucket "$bucket" --query 'LocationConstraint' --output text)
echo "$bucket -> ${region:-us-east-1}"
done
Étape 2 : Vérifier le blocage d'accès public et la configuration ACL de chaque bucket
Parcourez tous les buckets pour évaluer leurs blocs d'accès publics individuels et leurs octrois ACL.
# Vérifier les paramètres de blocage d'accès public par bucket
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
aws s3api get-public-access-block --bucket "$bucket" 2>/dev/null || echo " Aucun blocage d'accès public configuré"
# Vérifier les ACL pour les octrois publics
aws s3api get-bucket-acl --bucket "$bucket" \
--query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers` || Grantee.URI==`http://acs.amazonaws.com/groups/global/AuthenticatedUsers`]' \
--output json
done
Étape 3 : Analyser les politiques de bucket pour un accès trop permissif
Examinez les politiques de bucket pour les principaux génériques, les conditions manquantes et les déclarations qui autorisent un accès large.
# Extraire et analyser les politiques de bucket
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
policy=$(aws s3api get-bucket-policy --bucket "$bucket" --output text 2>/dev/null)
if [ -n "$policy" ]; then
echo "=== Politique de $bucket ==="
echo "$policy" | python3 -c "
import json, sys
policy = json.load(sys.stdin)
for stmt in policy.get('Statement', []):
principal = stmt.get('Principal', {})
effect = stmt.get('Effect', '')
if principal == '*' or principal == {'AWS': '*'}:
print(f' ATTENTION : {effect} avec un principal générique')
print(f' Actions : {stmt.get(\"Action\", \"\")}')
print(f' Condition : {stmt.get(\"Condition\", \"AUCUNE\")}')
"
fi
done
Étape 4 : Vérifier le chiffrement et les paramètres de versioning
Vérifiez que tous les buckets ont le chiffrement côté serveur activé et le versioning configuré pour la protection des données.
# Vérifier le statut de chiffrement et de versioning pour tous les buckets
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
# Configuration de chiffrement
aws s3api get-bucket-encryption --bucket "$bucket" 2>/dev/null \
&& echo " Chiffrement : ACTIVÉ" \
|| echo " Chiffrement : DÉSACTIVÉ"
# Statut du versioning
aws s3api get-bucket-versioning --bucket "$bucket" \
--query 'Status' --output text
# Statut de la journalisation
aws s3api get-bucket-logging --bucket "$bucket" \
--query 'LoggingEnabled' --output text 2>/dev/null
done
Étape 5 : Exécuter les vérifications spécifiques S3 de Prowler
Exécutez les vérifications S3 de Prowler alignées sur le benchmark CIS AWS Foundations.
# Exécuter les vérifications spécifiques S3 de Prowler
prowler aws \
--checks s3_bucket_public_access \
s3_bucket_default_encryption \
s3_bucket_policy_public_write_access \
s3_bucket_server_access_logging_enabled \
s3_bucket_versioning_enabled \
s3_bucket_acl_prohibited \
-M json-ocsf \
-o ./prowler-s3-audit/
# Voir le résumé
prowler aws --checks s3 -M csv -o ./prowler-s3-audit/
Étape 6 : Utiliser IAM Access Analyzer pour les constats S3 publics et inter-comptes
Utilisez IAM Access Analyzer pour identifier les buckets partagés en externe ou publiquement.
# Lister les constats d'Access Analyzer pour S3
aws accessanalyzer list-findings \
--analyzer-arn $(aws accessanalyzer list-analyzers --query 'analyzers[0].arn' --output text) \
--filter '{"resourceType": {"eq": ["AWS::S3::Bucket"]}}' \
--query 'findings[*].[resource,status,condition,principal]' \
--output table
# Créer un analyseur s'il n'en existe pas
aws accessanalyzer create-analyzer \
--analyzer-name s3-access-audit \
--type ACCOUNT
Étape 7 : Générer le rapport d'audit et remédier
Compilez les constats en un rapport actionnable et appliquez la remédiation pour les problèmes critiques.
# Remédiation rapide : Activer le blocage d'accès public sur un bucket
aws s3api put-public-access-block \
--bucket BUCKET_CIBLE \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
# Activer le chiffrement par défaut avec SSE-S3
aws s3api put-bucket-encryption \
--bucket BUCKET_CIBLE \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/aws/s3"},"BucketKeyEnabled":true}]}'
# Activer le versioning
aws s3api put-bucket-versioning \
--bucket BUCKET_CIBLE \
--versioning-configuration Status=Enabled
Concepts Clés
| Terme | Définition |
|---|---|
| S3 Block Public Access | Paramètres au niveau du compte et du bucket qui remplacent les ACL et les politiques pour empêcher l'accès public indépendamment des configurations de ressources individuelles |
| Politique de bucket | Politique de ressource basée sur JSON attachée à un bucket qui définit qui peut accéder au bucket et quelles actions ils peuvent effectuer |
| ACL (Access Control List) | Mécanisme de contrôle d'accès S3 hérité accordant des permissions à des comptes AWS ou à des groupes prédéfinis comme AllUsers ou AuthenticatedUsers |
| IAM Access Analyzer | Service AWS qui analyse les politiques de ressources pour identifier les ressources partagées avec des entités externes ou le public |
| Chiffrement côté serveur | Chiffrement appliqué par S3 au niveau de l'objet en utilisant SSE-S3, SSE-KMS ou SSE-C avant l'écriture des données sur le disque |
| CIS AWS Foundations Benchmark | Standard de bonne pratique de sécurité du Center for Internet Security avec des contrôles spécifiques pour la configuration des buckets S3 |
Outils & Systèmes
- AWS CLI : Interface principale pour interroger les configurations des buckets S3, les politiques, les ACL et les paramètres de chiffrement
- Prowler : Outil de sécurité open source avec plus de 50 vérifications spécifiques S3 alignées sur les contrôles CIS, PCI DSS et HIPAA
- IAM Access Analyzer : Service natif AWS pour la surveillance continue des politiques de ressources qui accordent un accès externe
- S3audit : Outil léger pour l'énumération rapide des buckets S3 publics dans un compte
- ScoutSuite : Outil d'audit multi-cloud qui collecte les données de configuration S3 et génère des rapports HTML avec évaluation des risques
Scénarios Courants
Scénario : Identification d'un bucket lisible publiquement contenant des données clients
Contexte : Un ingénieur sécurité reçoit une alerte Trusted Advisor concernant un bucket S3 accessible publiquement. Le bucket a été créé par une équipe de développement pour une démo et n'a jamais été verrouillé.
Approche :
- Exécutez
aws s3api get-bucket-aclet trouvez un octroi àAllUsersavec l'autorisationREAD - Vérifiez
get-bucket-policyet découvrez une politique avecPrincipal: "*"ets3:GetObject - Confirmez que le blocage d'accès public n'est pas activé au niveau du bucket ou du compte
- Énumérez le contenu du bucket pour évaluer la sensibilité des données
- Activez immédiatement le blocage d'accès public sur le bucket
- Examinez les événements de données S3 CloudTrail pour déterminer si un accès non autorisé a eu lieu
- Signalez le constat avec une chronologie, un inventaire des données et une confirmation de remédiation
Pièges : L'activation du blocage d'accès public peut casser les applications qui diffusent intentionnellement du contenu publiquement (sites web statiques). Vérifiez toujours l'utilisation prévue du bucket avant d'appliquer des restrictions. Vérifiez les distributions CloudFront ou d'autres services qui dépendent de l'accès public du bucket.
Format de sortie
Rapport d'audit des permissions des buckets S3
===============================================
Compte : 123456789012 (Production)
Date : 2026-02-23
Auditeur : Équipe d'ingénierie sécurité
Total buckets : 47
PARAMÈTRES AU NIVEAU DU COMPTE :
Blocage d'accès public : ACTIVÉ (tous les quatre paramètres)
CONSTATS CRITIQUES :
[S3-001] Accès en lecture public via ACL
Bucket : marketing-assets-prod
Problème : Le groupe AllUsers a obtenu l'autorisation READ via ACL
Risque : Tout utilisateur internet peut lister et télécharger le contenu du bucket
Sensibilité des données : Contient des actifs marketing orientés clients mais non sensibles
Remédiation : Supprimer l'octroi ACL AllUsers, activer le blocage d'accès public
[S3-002] Principal générique dans la politique de bucket
Bucket : data-exchange-partner
Problème : La politique autorise s3:GetObject avec Principal "*" et sans condition VPC/IP
Risque : Destiné à un accès partenaire mais accessible à quiconque connaît le nom du bucket
Remédiation : Ajouter une condition aws:SourceVpce ou aws:SourceIp pour restreindre l'accès
RÉSUMÉ :
Buckets avec accès public : 3 / 47
Buckets sans chiffrement : 5 / 47
Buckets sans versioning : 12 / 47
Buckets sans journalisation d'accès : 18 / 47
Buckets avec politiques trop larges : 7 / 47