auditing-aws-s3-bucket-permissions について
AWS のセキュリティ担当者向けに、S3 バケットの公開アクセス、ポリシー、ACL、暗号化、バージョニングを監査する手順をまとめたスキルです。調査結果の報告と修正方法も扱います。
主な機能
- 01アカウントとバケットの公開設定確認
- 02ACL とバケットポリシーの確認
- 03暗号化とバージョニングの検証
- 04Prowler の S3 チェック実行
- 05公開共有とクロスアカウント共有の検出
- 06結果の整理と修正手順の提示
活用シーン
- 01Trusted Advisor や Security Hub の公開警告を調査
- 02新規 AWS アカウントのストレージ基準を策定
- 03コンプライアンスに基づく定期的な権限レビュー
- 04認証情報の侵害後にアクセス可能な S3 リソースを確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill auditing-aws-s3-bucket-permissionsインストール後、Claude Code で/auditing-aws-s3-bucket-permissionsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/api-reference.mdscripts/agent.py詳細
AWS S3 バケットのアクセス許可を監査する
使用するタイミング
- AWS 環境のセキュリティ評価を実施し、一般公開されているデータを特定する場合
- 新しい AWS アカウントを導入し、ストレージリソースのセキュリティベースラインを確立する場合
- AWS Trusted Advisor または Security Hub から、S3 データが公開されている可能性に関するアラートを受けた場合
- コンプライアンスフレームワーク(SOC 2、PCI DSS、HIPAA)で、データアクセス制御の定期的なレビューが求められる場合
- データ侵害や認証情報の漏えいが発生し、アクセス可能なすべての S3 リソースを直ちに確認する必要がある場合
次の場合は使用しないでください:AWS 以外のオブジェクトストレージを監査する場合(プロバイダー固有のツールを使用してください)、リアルタイムで監視する場合(Lambda で S3 Event Notifications を使用してください)、または S3 のアクセスパターンを監査する場合(S3 Access Analyzer または CloudTrail S3 data events を使用してください)。
前提条件
s3:GetBucketPolicy、s3:GetBucketAcl、s3:GetBucketPublicAccessBlock、s3:GetEncryptionConfiguration、s3:ListAllMyBucketsの権限を持つ認証情報で設定された AWS CLI v2- CIS ベンチマークの自動チェック用に Prowler をインストール済みであること(
pip install prowler) - 公開バケットをすばやく検出するための S3audit または同様の列挙ツール
- 複数のアカウントを横断して監査する場合は、AWS Organizations へのアクセス権
- カスタム監査スクリプト用の boto3 を備えた Python 3.8 以降
ワークフロー
ステップ 1:すべての S3 バケットとアカウントレベルの Block Public Access を列挙する
まずアカウントレベルの S3 Block Public Access 設定を確認し、次に各バケットのリージョンとともにすべてのバケットを一覧表示します。
# Check account-level S3 Block Public Access settings
aws s3control get-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--output json
# List all buckets with creation dates
aws s3api list-buckets \
--query 'Buckets[*].[Name,CreationDate]' \
--output table
# Get bucket regions for each 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
ステップ 2:各バケットの Public Access Block と ACL の設定を確認する
すべてのバケットを調べ、個々の Public Access Block と ACL の許可設定を評価します。
# Check per-bucket Block Public Access settings
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 " No Block Public Access configured"
# Check ACL for public grants
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
ステップ 3:バケットポリシーを分析し、過度に広範なアクセスを確認する
バケットポリシーを確認し、ワイルドカードのプリンシパル、条件の欠如、広範なアクセスを許可するステートメントを調べます。
# Extract and analyze bucket policies
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 "=== $bucket policy ==="
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' WARNING: {effect} with wildcard principal')
print(f' Actions: {stmt.get(\"Action\", \"\")}')
print(f' Condition: {stmt.get(\"Condition\", \"NONE\")}')
"
fi
done
ステップ 4:暗号化とバージョニングの設定を確認する
データ保護のために、すべてのバケットでサーバー側の暗号化が有効になっており、バージョニングが設定されていることを確認します。
# Check encryption and versioning status for all buckets
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
# Encryption configuration
aws s3api get-bucket-encryption --bucket "$bucket" 2>/dev/null \
&& echo " Encryption: ENABLED" \
|| echo " Encryption: DISABLED"
# Versioning status
aws s3api get-bucket-versioning --bucket "$bucket" \
--query 'Status' --output text
# Logging status
aws s3api get-bucket-logging --bucket "$bucket" \
--query 'LoggingEnabled' --output text 2>/dev/null
done
ステップ 5:Prowler の S3 専用チェックを実行する
CIS AWS Foundations Benchmark に沿った、Prowler の S3 に特化したチェックを実行します。
# Run Prowler S3-specific checks
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/
# View summary
prowler aws --checks s3 -M csv -o ./prowler-s3-audit/
ステップ 6:IAM Access Analyzer を使用して、S3 の公開およびクロスアカウントに関する検出結果を確認する
IAM Access Analyzer を活用し、外部または一般に共有されているバケットを特定します。
# List Access Analyzer findings for 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
# Create an analyzer if one does not exist
aws accessanalyzer create-analyzer \
--analyzer-name s3-access-audit \
--type ACCOUNT
ステップ 7:監査レポートを作成して問題を修正する
検出結果を実行可能なレポートにまとめ、重大な問題を修正します。
# Quick remediation: Enable Block Public Access on a bucket
aws s3api put-public-access-block \
--bucket TARGET_BUCKET \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
# Enable default encryption with SSE-S3
aws s3api put-bucket-encryption \
--bucket TARGET_BUCKET \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/aws/s3"},"BucketKeyEnabled":true}]}'
# Enable versioning
aws s3api put-bucket-versioning \
--bucket TARGET_BUCKET \
--versioning-configuration Status=Enabled
主な概念
| 用語 | 定義 |
|---|---|
| S3 Block Public Access | ACL とポリシーを上書きして、個々のリソース設定にかかわらず公開アクセスを防ぐ、アカウントレベルおよびバケットレベルの設定 |
| Bucket Policy | バケットに適用される JSON ベースのリソースポリシーで、バケットにアクセスできるユーザーと実行できるアクションを定義します |
| ACL(Access Control List) | AllUsers や AuthenticatedUsers などの事前定義されたグループ、または AWS アカウントにアクセス許可を付与する、従来の S3 アクセス制御メカニズム |
| IAM Access Analyzer | リソースポリシーを分析し、外部のエンティティや一般に共有されているリソースを特定する AWS サービス |
| Server-Side Encryption | データをディスクに書き込む前に、SSE-S3、SSE-KMS、または SSE-C を使用してオブジェクトレベルで S3 が適用する暗号化 |
| CIS AWS Foundations Benchmark | Center for Internet Security によるセキュリティのベストプラクティス標準で、S3 バケットの設定に関する具体的な管理策を定めています |
ツールとシステム
- AWS CLI:S3 バケットの設定、ポリシー、ACL、暗号化設定を照会するための主要なインターフェースです
- Prowler:CIS、PCI DSS、HIPAA の管理策に準拠した、S3 固有の 50 以上のチェックを備えるオープンソースのセキュリティツールです
- IAM Access Analyzer:外部アクセスを許可するリソースポリシーを継続的に監視する AWS ネイティブのサービスです
- S3audit:アカウント全体のパブリックな S3 バケットをすばやく列挙するための軽量ツールです
- ScoutSuite:S3 の設定データを収集し、リスク評価付きの HTML レポートを生成するマルチクラウド監査ツールです
よくあるシナリオ
シナリオ:顧客データを含む、一般公開で読み取り可能なバケットの特定
コンテキスト:セキュリティエンジニアが、一般公開されている S3 バケットに関する Trusted Advisor のアラートを受け取ります。このバケットはデモ用に開発チームが作成したもので、アクセス制限が設定されないままでした。
アプローチ:
aws s3api get-bucket-aclを実行し、AllUsersにREAD権限を付与する許可を見つけますget-bucket-policyを確認し、Principal: "*"とs3:GetObjectを含むポリシーを見つけます- バケットレベルまたはアカウントレベルでパブリックアクセスブロックが有効になっていないことを確認します
- バケットの内容を列挙し、データの機密性を評価します
- バケットでパブリックアクセスブロックを直ちに有効にします
- CloudTrail の S3 データイベントを確認し、不正アクセスが発生したかどうかを判断します
- タイムライン、データの一覧、修正の確認を含めて検出結果を報告します
注意点:パブリックアクセスブロックを有効にすると、コンテンツを意図的に一般公開するアプリケーション(静的ウェブサイトなど)が動作しなくなることがあります。制限を適用する前に、必ずバケットの用途を確認してください。バケットへのパブリックアクセスに依存する CloudFront ディストリビューションやその他のサービスがないか確認してください。
出力形式
S3 Bucket Permissions Audit Report
=====================================
Account: 123456789012 (Production)
Date: 2026-02-23
Auditor: Security Engineering Team
Total Buckets: 47
ACCOUNT-LEVEL SETTINGS:
Block Public Access: ENABLED (all four settings)
CRITICAL FINDINGS:
[S3-001] Public Read Access via ACL
Bucket: marketing-assets-prod
Issue: AllUsers group granted READ permission via ACL
Risk: Any internet user can list and download bucket contents
Data Sensitivity: Contains customer-facing but non-sensitive marketing assets
Remediation: Remove AllUsers ACL grant, enable Block Public Access
[S3-002] Wildcard Principal in Bucket Policy
Bucket: data-exchange-partner
Issue: Policy allows s3:GetObject with Principal "*" and no VPC/IP condition
Risk: Intended for partner access but accessible to anyone with the bucket name
Remediation: Add aws:SourceVpce or aws:SourceIp condition to restrict access
SUMMARY:
Buckets with public access: 3 / 47
Buckets without encryption: 5 / 47
Buckets without versioning: 12 / 47
Buckets without access logging: 18 / 47
Buckets with overly broad policies: 7 / 47