remediating-s3-bucket-misconfiguration について
AWS のセキュリティチーム向けに、S3 バケットの公開設定や暗号化不足を検出・修正する手順を示します。監査、修復、監視、組織全体の予防策を扱います。
主な機能
- 01公開・設定不備のバケット検出
- 02アカウント単位の Block Public Access
- 03バケットポリシーの制限と ACL 無効化
- 04デフォルトのサーバー側暗号化
- 05アクセスログとアラートの設定
- 06SCP と Config による予防
活用シーン
- 01公開設定や暗号化不足の警告への対応
- 02公開バケットによる漏えいの調査
- 03ストレージセキュリティ監査の準備
- 04AWS Organization 全体の予防策の整備
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill remediating-s3-bucket-misconfigurationインストール後、Claude Code で/remediating-s3-bucket-misconfigurationを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
S3 バケットの設定ミスを修正する
使用する場面
- AWS Config または Security Hub が、パブリックアクセスが可能な S3 バケットや暗号化が有効でない S3 バケットを報告した場合
- セキュリティスキャンで、Principal "*"(全員)にアクセスを許可する S3 バケットポリシーが見つかった場合
- ストレージのセキュリティ制御に関する証拠を求められるデータ保護監査に備える場合
- パブリックアクセス可能な S3 オブジェクトに関するデータ漏えいインシデントに対応する場合
- AWS Organization 全体で新しい S3 バケットの作成に対する予防的な制御を確立する場合
次の用途には使用しないでください:Azure Blob Storage または GCP Cloud Storage の設定ミス、S3 データの分類(implementing-cloud-dlp-policy を参照)、セキュリティとは無関係な S3 アクセスパターンの分析。
前提条件
- S3 の管理権限(s3:, s3-outposts:)を持つ AWS アカウント
- S3 リソースのコンプライアンス評価に使用する AWS Config が有効であること
- アクセス監査用に S3 データイベントを記録する AWS CloudTrail
- S3 バケット内の機密データを検出する Macie が有効であること
ワークフロー
ステップ 1:パブリックアクセスが可能なバケットと設定ミスのあるバケットをすべて特定する
複数の検出方法を使用して、パブリックアクセスが可能な S3 バケットを特定します。手動での確認ではなく、AWS Config ルール、S3 Access Analyzer、Macie を活用します。
# Enable S3 Access Analyzer for external access detection
aws accessanalyzer create-analyzer \
--analyzer-name s3-analyzer \
--type ACCOUNT
# List all S3 buckets with public access indicators
aws s3api list-buckets --query 'Buckets[*].Name' --output text | while read bucket; do
public_status=$(aws s3api get-public-access-block --bucket "$bucket" 2>/dev/null)
if [ $? -ne 0 ]; then
echo "NO PUBLIC ACCESS BLOCK: $bucket"
fi
done
# Check bucket policies for public access grants
aws s3api list-buckets --query 'Buckets[*].Name' --output text | while read bucket; do
policy=$(aws s3api get-bucket-policy --bucket "$bucket" 2>/dev/null)
if echo "$policy" | grep -q '"Principal":"*"' 2>/dev/null; then
echo "PUBLIC POLICY DETECTED: $bucket"
fi
done
# Use AWS Config to find non-compliant buckets
aws configservice get-compliance-details-by-config-rule \
--config-rule-name s3-bucket-public-read-prohibited \
--compliance-types NON_COMPLIANT \
--query 'EvaluationResults[*].EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId'
ステップ 2:アカウントレベルで S3 Block Public Access を有効にする
安全策として、AWS アカウントレベルで 4 つの Block Public Access 設定を適用します。これにより、個々のバケットポリシーや ACL にかかわらず、アカウント内のどのバケットもパブリックにできなくなります。
# Enable account-level Block Public Access (all four settings)
aws s3control put-public-access-block \
--account-id 123456789012 \
--public-access-block-configuration '{
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}'
# Verify account-level settings
aws s3control get-public-access-block --account-id 123456789012
# Enable at bucket level for defense in depth
aws s3api put-public-access-block \
--bucket production-data-bucket \
--public-access-block-configuration '{
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}'
ステップ 3:バケットポリシーと ACL を監査し、修正する
すべてのバケットポリシーを確認して、過度に許容的な Principal ステートメントを特定し、レガシー ACL を削除します。バケット所有権コントロールを適用し、ACL を完全に無効にします。
# Remove a public bucket policy
aws s3api delete-bucket-policy --bucket exposed-bucket
# Replace with a restrictive policy
aws s3api put-bucket-policy --bucket exposed-bucket --policy '{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyUnencryptedTransport",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::exposed-bucket",
"arn:aws:s3:::exposed-bucket/*"
],
"Condition": {
"Bool": {"aws:SecureTransport": "false"}
}
},
{
"Sid": "AllowOnlyVPCEndpoint",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::exposed-bucket",
"arn:aws:s3:::exposed-bucket/*"
],
"Condition": {
"StringNotEquals": {"aws:SourceVpce": "vpce-0abc123def456"}
}
}
]
}'
# Enforce bucket owner for all objects (disable ACLs)
aws s3api put-bucket-ownership-controls --bucket exposed-bucket \
--ownership-controls '{"Rules": [{"ObjectOwnership": "BucketOwnerEnforced"}]}'
ステップ 4:デフォルトの暗号化を強制する
すべてのバケットで、AWS KMS または AES-256 によるデフォルトのサーバー側暗号化を有効にします。暗号化されていないオブジェクトのアップロードを拒否するバケットポリシーを追加します。
# Enable default KMS encryption
aws s3api put-bucket-encryption --bucket production-data-bucket \
--server-side-encryption-configuration '{
"Rules": [{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/key-id"
},
"BucketKeyEnabled": true
}]
}'
# Deny unencrypted uploads via bucket policy
aws s3api put-bucket-policy --bucket production-data-bucket --policy '{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyUnencryptedUploads",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::production-data-bucket/*",
"Condition": {
"StringNotEquals": {"s3:x-amz-server-side-encryption": ["aws:kms", "AES256"]}
}
}]
}'
ステップ 5:アクセスログ記録とモニタリングを有効にする
S3 サーバーアクセスログと CloudTrail データイベントを設定して、すべてのオブジェクトレベルの操作を追跡します。不審なアクセスパターンを通知する EventBridge ルールを設定します。
# Enable server access logging
aws s3api put-bucket-logging --bucket production-data-bucket \
--bucket-logging-status '{
"LoggingEnabled": {
"TargetBucket": "s3-access-logs-bucket",
"TargetPrefix": "production-data-bucket/"
}
}'
# Enable CloudTrail S3 data events
aws cloudtrail put-event-selectors --trail-name management-trail \
--event-selectors '[{
"ReadWriteType": "All",
"DataResources": [{
"Type": "AWS::S3::Object",
"Values": ["arn:aws:s3:::production-data-bucket/"]
}]
}]'
ステップ 6:SCP と Config で予防的な制御を導入する
Service Control Policies を使用して、組織全体で Block Public Access が無効にされるのを防ぎます。自動修復機能を備えた AWS Config ルールを導入します。
# SCP preventing Block Public Access removal
aws organizations create-policy \
--name PreventS3PublicAccess \
--type SERVICE_CONTROL_POLICY \
--content '{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyRemovePublicAccessBlock",
"Effect": "Deny",
"Action": [
"s3:PutBucketPublicAccessBlock",
"s3:PutAccountPublicAccessBlock"
],
"Resource": "*",
"Condition": {
"StringNotLike": {"aws:PrincipalArn": "arn:aws:iam::*:role/SecurityAdmin"}
}
}]
}'
主要な概念
| 用語 | 定義 |
|---|---|
| S3 Block Public Access | S3 リソースへのパブリックアクセスを許可するポリシーや ACL をすべて上書きする、アカウントレベルおよびバケットレベルの 4 つの設定 |
| Bucket Policy | どのような条件で誰がどのオブジェクトにアクセスできるかを定義する、S3 バケットにアタッチされた JSON ベースのリソースポリシー |
| ACL(Access Control List) | バケットまたはオブジェクトレベルでアクセス許可を付与するレガシー S3 アクセス方式。BucketOwnerEnforced によって無効にする必要があります |
| BucketOwnerEnforced | バケット上のすべての ACL を無効にする所有権コントロール設定。アクセス制御の権限をバケット所有者だけに与えます |
| Server-Side Encryption | AES-256(SSE-S3)、AWS KMS(SSE-KMS)、またはカスタマー提供キー(SSE-C)を使用して、保存中のオブジェクトを自動的に暗号化すること |
| VPC Endpoint | VPC と S3 の間のプライベート接続。VPC 内から発信されたトラフィックにバケットへのアクセスを制限します |
| S3 Access Analyzer | アカウントまたは組織の外部エンティティと共有されている S3 バケットを特定する IAM Access Analyzer の機能 |
ツールとシステム
- AWS Config:管理ルールに照らして S3 バケットのコンプライアンスを評価し、非準拠リソースの自動修復をトリガーします
- Amazon Macie:S3 バケット内の機密データを検出して分類し、どの設定ミスが最も高いデータ漏えいリスクをもたらすかを特定します
- IAM Access Analyzer:外部プリンシパルにアクセスを許可するポリシーまたは ACL を持つ S3 バケットを特定します
- S3 Storage Lens:S3 の使用パターン、アクセス指標、セキュリティ上の異常を組織全体で可視化します
- Prowler:CIS ベンチマークとベストプラクティスに照らして S3 のセキュリティ設定をチェックするオープンソースツールです
よくあるシナリオ
シナリオ:個人識別情報(PII)を含む、一般公開された S3 バケットからのデータ侵害
状況:セキュリティ研究者から、銀行振込の PDF 273,000 件を含む S3 バケットが一般公開されているとの報告がありました。このバケットは、外部パートナーとファイルを共有する必要があった開発者が作成し、ACL を public-read に設定していました。
対応:
- 露出を止めるため、該当するバケットで直ちに Block Public Access を有効にします
- BucketOwnerEnforced の所有権コントロールを設定して、すべてのパブリック ACL を無効にします
- CloudTrail と S3 アクセスログを監査し、露出したオブジェクトにアクセスした IP アドレスを特定します
- バケットで Macie を実行し、露出した PII の種類を分類して、規制上の通知要件を評価します
- すべてのバケットで再発を防ぐため、アカウントレベルの Block Public Access を有効にします
- SecurityAdmin 以外のプリンシパルによる Block Public Access 設定の変更を防止する SCP をデプロイします
- 正当なパートナーとの共有用途に、署名付き URL の仕組みまたは S3 Access Point を作成します
注意点:パブリックアクセスを設定したチームに知らせずに Block Public Access を有効にすると、そのチームのワークフローが中断されます。修復の前にアクセスログを分析しないと、露出したデータに誰がアクセスしたかの証拠が失われます。
出力形式
S3 Bucket Security Remediation Report
=======================================
Account: 123456789012
Assessment Date: 2025-02-23
Buckets Scanned: 156
ACCOUNT-LEVEL CONTROLS:
Block Public Access: ENABLED (all four settings)
SCP Preventing Removal: DEPLOYED
CRITICAL FINDINGS (Remediated):
[S3-001] production-uploads - Public READ via ACL
Status: REMEDIATED - BucketOwnerEnforced applied
Objects Exposed: 273,412
Duration of Exposure: 47 days
Unique External IPs Accessed: 1,247
[S3-002] analytics-export - Public bucket policy (Principal: *)
Status: REMEDIATED - Policy replaced with VPC endpoint restriction
Sensitive Data (Macie): 12,400 objects with PII detected
HIGH FINDINGS:
[S3-003] 14 buckets missing default encryption
Status: REMEDIATED - KMS encryption enabled
[S3-004] 8 buckets without server access logging
Status: REMEDIATED - Logging enabled to centralized log bucket
SUMMARY:
Buckets Remediated: 24/156
Encryption Coverage: 100%
Access Logging Coverage: 100%
Block Public Access: 156/156 buckets