AWS S3バケット権限監査 は何をしますか?
使用すべきタイミング
- AWS環境のセキュリティ評価を実施し、公開されているデータを特定する場合
- 新しいAWSアカウントをオンボーディングし、ストレージリソースのセキュリティベースラインを確立する場合
- AWS Trusted AdvisorまたはSecurity HubからS3データ露出に関するアラートに対応する場合
- SOC 2、PCI DSS、HIPAAなどのコンプライアンスフレームワークでデータアクセス制御の定期的なレビューが必要な場合
- 情報漏洩や認証情報の漏洩後、アクセス可能な全S3リソースを直ちに確認する必要がある場合
使用すべきでないケース: AWS以外のオブジェクトストレージの監査(プロバイダ固有のツールを使用)、リアルタイム監視(S3イベント通知とLambdaを使用)、S3アクセスパターンの監査(S3 Access AnalyzerまたはCloudTrail S3データイベントを使用)には使用しないでください。
前提条件
s3:GetBucketPolicy、s3:GetBucketAcl、s3:GetBucketPublicAccessBlock、s3:GetEncryptionConfiguration、s3:ListAllMyBuckets権限を持つ認証情報が設定されたAWS CLI v2- Prowlerがインストールされていること(
pip install prowler)自動化されたCISベンチマークチェック用 - S3auditまたは同様の列挙ツール(公開バケットの迅速な検出用)
- 複数アカウントを監査する場合はAWS Organizationsへのアクセス
- カスタム監査スクリプト用のPython 3.8+とboto3
ワークフロー
ステップ1: 全S3バケットとアカウントレベルのブロックパブリックアクセスを列挙する
最初にアカウントレベルのS3 Block Public Access設定を確認し、次にすべてのバケットをリージョン情報とともに一覧表示します。
# アカウントレベルのS3 Block Public Access設定を確認
aws s3control get-public-access-block \
--account-id $(aws sts get-caller-identity --query Account --output text) \
--output json
# 作成日とともに全バケットを一覧表示
aws s3api list-buckets \
--query 'Buckets[*].[Name,CreationDate]' \
--output table
# 各バケットのリージョンを取得
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権限を評価します。
# バケットごとのBlock Public Access設定を確認
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 " Block Public Accessが設定されていません"
# 公開権限を持つACLを確認
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: 過度に寛容なアクセスを許可するバケットポリシーを分析する
ワイルドカードプリンシパル、欠落した条件、および広範なアクセスを許可するステートメントについてバケットポリシーを確認します。
# バケットポリシーを抽出して分析
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 ポリシー ==="
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' 警告: {effect} ワイルドカードプリンシパル')
print(f' アクション: {stmt.get(\"Action\", \"\")}')
print(f' 条件: {stmt.get(\"Condition\", \"なし\")}')
"
fi
done
ステップ4: 暗号化とバージョニング設定を確認する
すべてのバケットでサーバー側の暗号化が有効であり、データ保護のためにバージョニングが設定されていることを確認します。
# 全バケットの暗号化とバージョニングステータスを確認
for bucket in $(aws s3api list-buckets --query 'Buckets[*].Name' --output text); do
echo "=== $bucket ==="
# 暗号化設定
aws s3api get-bucket-encryption --bucket "$bucket" 2>/dev/null \
&& echo " 暗号化: 有効" \
|| echo " 暗号化: 無効"
# バージョニングステータス
aws s3api get-bucket-versioning --bucket "$bucket" \
--query 'Status' --output text
# ログ記録ステータス
aws s3api get-bucket-logging --bucket "$bucket" \
--query 'LoggingEnabled' --output text 2>/dev/null
done
ステップ5: ProwlerのS3固有チェックを実行する
CIS AWS Foundations Benchmarkに沿ったProwlerのS3特化型チェックを実行します。
# Prowler S3固有チェックを実行
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/
# サマリーを表示
prowler aws --checks s3 -M csv -o ./prowler-s3-audit/
ステップ6: IAM Access AnalyzerをS3の公開・クロスアカウント発見事項に使用する
IAM Access Analyzerを活用して、外部または公開で共有されているバケットを特定します。
# S3に関するAccess Analyzerの検出結果を一覧表示
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
# アナライザーが存在しない場合は作成
aws accessanalyzer create-analyzer \
--analyzer-name s3-access-audit \
--type ACCOUNT
ステップ7: 監査レポートを生成し、修復する
調査結果を実用的なレポートにまとめ、重大な問題に対して修復を適用します。
# クイック修復: バケットでBlock Public Accessを有効化
aws s3api put-public-access-block \
--bucket ターゲットバケット \
--public-access-block-configuration \
'BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true'
# SSE-S3でデフォルト暗号化を有効化
aws s3api put-bucket-encryption \
--bucket ターゲットバケット \
--server-side-encryption-configuration \
'{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"aws:kms","KMSMasterKeyID":"alias/aws/s3"},"BucketKeyEnabled":true}]}'
# バージョニングを有効化
aws s3api put-bucket-versioning \
--bucket ターゲットバケット \
--versioning-configuration Status=Enabled
主要な概念
| 用語 | 定義 |
|---|---|
| S3 Block Public Access | アカウントレベルおよびバケットレベルでACLやポリシーを上書きし、個々のリソース設定に関係なくパブリックアクセスを防止する設定 |
| バケットポリシー | バケットにアタッチされるJSONベースのリソースポリシー。誰がバケットにアクセスでき、どのようなアクションを実行できるかを定義する |
| ACL (アクセス制御リスト) | レガシーなS3アクセス制御メカニズム。AWSアカウントやAllUsers、AuthenticatedUsersなどの定義済みグループに権限を付与する |
| IAM Access Analyzer | リソースポリシーを分析し、外部エンティティや一般公開と共有されているリソースを特定するAWSサービス |
| サーバー側暗号化 | S3がオブジェクトレベルでSSE-S3、SSE-KMS、またはSSE-Cを使用して、データをディスクに書き込む前に適用する暗号化 |
| CIS AWS Foundations Benchmark | Center for Internet Securityによるセキュリティベストプラクティス標準。S3バケット設定に関する特定のコントロールを含む |
ツールとシステム
- AWS CLI: S3バケットの設定、ポリシー、ACL、暗号化設定を照会するための主要インターフェース
- Prowler: オープンソースのセキュリティツール。CIS、PCI DSS、HIPAAのコントロールに準拠した50以上のS3固有チェックを提供
- IAM Access Analyzer: 外部アクセスを許可するリソースポリシーを継続的に監視するAWSネイティブサービス
- S3audit: アカウント全体の公開S3バケットを迅速に列挙するための軽量ツール
- ScoutSuite: マルチクラウド監査ツール。S3設定データを収集し、リスクスコア付きのHTMLレポートを生成
一般的なシナリオ
シナリオ: 顧客データを含む公開読み取り可能バケットの特定
コンテキスト: セキュリティエンジニアがTrusted Advisorから公開アクセス可能なS3バケットに関するアラートを受け取ります。このバケットは開発チームがデモ用に作成したもので、ロックダウンされていませんでした。
アプローチ:
aws s3api get-bucket-aclを実行し、AllUsersにREAD権限が付与されていることを確認get-bucket-policyを確認し、Principal: "*"とs3:GetObjectを含むポリシーを発見- バケットまたはアカウントレベルでBlock Public Accessが有効になっていないことを確認
- バケットの内容を列挙し、データの機密性を評価
- 直ちにバケットでBlock Public Accessを有効化
- CloudTrail S3データイベントを確認し、不正アクセスが発生したかどうかを判断
- タイムライン、データインベントリ、修復確認を含む調査結果を報告
落とし穴: Block Public Accessを有効にすると、意図的にコンテンツを公開しているアプリケーション(静的ウェブサイト)が壊れる可能性があります。制限を適用する前に、バケットの意図された使用目的を常に確認してください。バケットの公開アクセスに依存するCloudFrontディストリビューションやその他のサービスがないか確認してください。
出力形式
S3バケット権限監査レポート
=====================================
アカウント: 123456789012 (本番環境)
日付: 2026-02-23
監査担当者: セキュリティエンジニアリングチーム
バケット総数: 47
アカウントレベルの設定:
Block Public Access: 有効 (4つの設定すべて)
重大な発見事項:
[S3-001] ACLによる公開読み取りアクセス
バケット: marketing-assets-prod
問題: AllUsersグループにACL経由でREAD権限が付与
リスク: インターネット上の任意のユーザーがバケットコンテンツを一覧表示およびダウンロード可能
データ機密性: 顧客向けだが機密性の低いマーケティングアセットを含む
修復: AllUsers ACL権限を削除し、Block Public Accessを有効化
[S3-002] バケットポリシー内のワイルドカードプリンシパル
バケット: data-exchange-partner
問題: ポリシーにより、Principal "*" かつVPC/IP条件なしでs3:GetObjectを許可
リスク: パートナーアクセスを意図しているが、バケット名を知っている誰でもアクセス可能
修復: aws:SourceVpceまたはaws:SourceIp条件を追加してアクセスを制限
サマリー:
公開アクセス可能なバケット: 3 / 47
暗号化されていないバケット: 5 / 47
バージョニングなしのバケット: 12 / 47
アクセスログなしのバケット: 18 / 47
過度に広範なポリシーを持つバケット: 7 / 47