S3.2 / S3.3 の BPA 評価ロジック検証
このページの位置づけ
S3.2 / S3.3 が「結果ベース(アカウント/バケットレベル BPA + ポリシー + ACL の総合判断)」と呼ばれる根拠を、実機検証で確定させるページ。S3.2・S3.3・S3.8 の各記事から参照される補足検証ページ。
BPA における「パブリック」の定義
BPA の 4 設定を理解する前に、S3 がバケットポリシーを「パブリック」と判定するロジックを押さえておく必要がある。S3 はバケットポリシーを評価する際、まずポリシーをパブリックと仮定し、non-public である証拠を探すという方針を取る(公式ドキュメント: The meaning of “public”)。
non-public と判定されるには、Principal や CIDR などがワイルドカードを含まない固定値で指定されているか、以下のいずれかの Condition キーで固定値の制限が付いている必要がある。
aws:SourceIp(CIDR ブロック)aws:SourceArn/aws:SourceVpc/aws:SourceVpceaws:SourceOwner/aws:SourceAccountaws:userid(AROLEID:*パターン以外)s3:DataAccessPointArn/s3:DataAccessPointAccount
例:
"Principal": "*"のみ → パブリック"Principal": "*"+"Condition": {"StringEquals": {"aws:SourceVpc": "vpc-12345"}}→ non-public(特定 VPC に制限)"Principal": "*"+"Condition": {"StringLike": {"aws:SourceVpc": "vpc-*"}}→ パブリック(ワイルドカード)
本検証では Principal: "*" を使い、パブリックと判定されるポリシーを設定する。
BPA の 4 設定(全レベル共通)
BPA は「読み取り/書き込み」ではなく「ACL 経路/ポリシー経路」×「予防/事後対応」で分類される。この 4 設定名はアカウントレベル・バケットレベル・アクセスポイントレベルで共通である。
| 経路 | 予防(新規設定をブロック) | 事後対応(既存設定の効果を無効化) |
|---|---|---|
| ACL 経路 | BlockPublicAcls | IgnorePublicAcls |
| ポリシー経路 | BlockPublicPolicy | RestrictPublicBuckets |
BlockPublicPolicy= パブリック(上記定義)と判定されるバケットポリシーを設定する API 呼び出し(PutBucketPolicy)自体をブロック(公式ドキュメント)。既にパブリックポリシーが設定されているバケットには影響しない(既存ポリシーは撤去されない)RestrictPublicBuckets= パブリックと判定されるポリシーが既に設定されているバケットへのアクセスを、バケットオーナーと AWS サービスのみに制限
S3.2 / S3.3 の評価ロジック
S3_BUCKET_PUBLIC_READ_PROHIBITED(S3.2)と S3_BUCKET_PUBLIC_WRITE_PROHIBITED(S3.3)の評価ロジックは同じ構造である。以下のポリシー経路の条件と ACL 経路の条件が両方満たされたときのみ COMPLIANT になる。
ポリシー経路の条件: 以下のいずれかが成立
- アカウントレベル/バケットレベル BPA の
BlockPublicPolicyまたはRestrictPublicBucketsがtrue(どこかのレベルで 1 つでもtrueなら成立) - バケットポリシーがパブリックアクセスを許可していない
ACL 経路の条件: 以下のいずれかが成立
- アカウントレベル/バケットレベル BPA の
BlockPublicAclsまたはIgnorePublicAclsがtrue(どこかのレベルで 1 つでもtrueなら成立) - バケット ACL がパブリックアクセスを許可していない
本検証では ACL 経路を対象外とする。2023 年 4 月以降に作成されたバケットでは Object Ownership が BucketOwnerEnforced(デフォルト)となり、バケット ACL もオブジェクト ACL も設定自体ができず無効化されている(詳細は S3 の Object Ownership 公式ドキュメント)。ACL そのものが存在しないため、BlockPublicPolicy / RestrictPublicBuckets の値に関わらず ACL 経由のパブリック公開は発生しない。パブリック公開はバケットポリシー経由のみで発生するため、本検証ではポリシー経路の 2 設定(BlockPublicPolicy / RestrictPublicBuckets)だけを変えて実測する。
検証で確かめたいこと
パブリック読み書きが許可されたバケットに対して、以下を確認する。
- ポリシー経路 2 設定はどちらか一方で条件を満たすか: バケットレベル BPA の
BlockPublicPolicyとRestrictPublicBucketsのどちらか一方がtrueであれば COMPLIANT になるか - アカウントレベル BPA も評価対象か: バケットレベル BPA が全無効でも、アカウントレベル BPA で条件を満たせば COMPLIANT になるか
- 「片方だけ true」の安全性:
BlockPublicPolicy=true, RestrictPublicBuckets=falseのような片方だけ有効な状態で、Security Hub の判定と実際のアクセス制御は一致するか
ACL 経路は本検証の対象外とする(詳細は前述のセクション参照)。
検証結果のサマリ
実機検証で以下の 3 点が確認できた。
- ポリシー経路 2 設定はどちらか一方で条件を満たす: バケットレベル BPA の
BlockPublicPolicyまたはRestrictPublicBucketsのどちらか一方がtrueなら COMPLIANT(パターン 2 / 3) - アカウントレベル BPA も評価対象に含まれる: バケットレベル BPA を全無効にしても、アカウントレベル BPA のポリシー経路が有効なら COMPLIANT(パターン 5)
BlockPublicPolicy=true, RestrictPublicBuckets=falseの組み合わせは Security Hub 上 COMPLIANT になるが、既存のパブリックポリシーは有効なままで実際のアクセスは継続する(Security Hub が COMPLIANT でも実際にはパブリックアクセスが継続するケース を参照)
検証マトリクス
バケットポリシーでパブリック読み書きを許可した状態で、BlockPublicPolicy と RestrictPublicBuckets の組み合わせを変えて S3.2 / S3.3 の評価結果を確認した。
| # | レベル | BlockPublicPolicy | RestrictPublicBuckets | S3.2 | S3.3 | 意味 |
|---|---|---|---|---|---|---|
| 1 | バケット | false | false | NON_COMPLIANT | NON_COMPLIANT | 両方無効にするとバケットポリシーが評価され NON_COMPLIANT |
| 2 | バケット | false | true | COMPLIANT | COMPLIANT | RestrictPublicBuckets 単独で COMPLIANT(片方だけで十分であることの実測) |
| 3 | バケット | true | false | COMPLIANT | COMPLIANT | BlockPublicPolicy 単独でも COMPLIANT。ただし実際にはパブリックアクセスが継続する(後述) |
| 4 | バケット | true | true | COMPLIANT | COMPLIANT | 推奨設定。両方有効で確実に保護される |
| 5 | アカウント | true | true | COMPLIANT | COMPLIANT | バケットレベル全無効でもアカウントレベルで有効なら COMPLIANT。評価対象は両レベル |
このマトリクスから以下を実測できる。
- パターン 2 と 3:
BlockPublicPolicyとRestrictPublicBucketsのどちらか一方が有効なら COMPLIANT - パターン 5: バケットレベルで両方無効でもアカウントレベルが有効なら COMPLIANT
Security Hub が COMPLIANT でも実際にはパブリックアクセスが継続するケース
パターン 3(BlockPublicPolicy=true, RestrictPublicBuckets=false)は Security Hub 上は COMPLIANT と判定されるが、既存のパブリックポリシーは依然として有効でパブリックアクセスが継続する状態になる。
理由
BlockPublicPolicyはパブリックなポリシーの新規設定(PutBucketPolicyAPI 呼び出し)をブロックする予防設定。既にパブリックポリシーが設定されているバケットには影響しない(既存ポリシーは撤去されない)RestrictPublicBucketsは既存のパブリックポリシーの効果を無効化する事後対応設定。falseのため既存のパブリックポリシーが有効なまま
つまり、パブリックポリシーが既に設定されている状態でこの組み合わせにすると、CSPM(S3.2 / S3.3)は「問題なし」と判定するが、インターネットからの実際のアクセスは引き続き可能、という乖離が発生する。
推奨設定
既にパブリックポリシーが設定されている可能性を考慮すると、BlockPublicPolicy=true と RestrictPublicBuckets=true の両方を有効にすべきである。S3.8(バケットレベル BPA の 4 設定すべてが有効か)はこの両方 + ACL 経路 2 設定の計 4 設定すべてが有効なときのみ COMPLIANT になる設定ベースのチェックで、この乖離を補う役割を持つ。
検証環境
--profile 指定がない場合は Workload アカウントで実行する。export AWS_PROFILE=Workload でデフォルトを設定しておくと便利。
検証の流れ
flowchart LR
A[1. テストバケット作成] --> B[2. パブリックポリシー設定]
B --> C[3. BPA 組み合わせ検証<br>5 パターン]
C --> D[4. クリーンアップ]
1. テストバケット作成
aws s3api create-bucket \
--bucket <テストバケット名> \
--create-bucket-configuration LocationConstraint=ap-northeast-1 \
--region ap-northeast-1{
"Location": "http://<テストバケット名>.s3.amazonaws.com/",
"BucketArn": "arn:aws:s3:::<テストバケット名>"
}2. パブリック読み書きポリシーの設定
まずバケットレベル BPA を全無効化してからポリシーを設定する(BlockPublicPolicy=true だとパブリックポリシーの設定がブロックされるため)。
バケットレベル BPA 全無効化
aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false \
--region ap-northeast-1
(出力なし)バケットレベル BPA 全無効化の確認
aws s3api get-public-access-block \
--bucket <テストバケット名> \
--region ap-northeast-1{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": false,
"IgnorePublicAcls": false,
"BlockPublicPolicy": false,
"RestrictPublicBuckets": false
}
}パブリック読み書きポリシーを設定
aws s3api put-bucket-policy \
--bucket <テストバケット名> \
--policy '{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::<テストバケット名>/*"
}
]
}' \
--region ap-northeast-1
(出力なし)ポリシーの確認
aws s3api get-bucket-policy \
--bucket <テストバケット名> \
--output json \
--region ap-northeast-1 | jq -r '.Policy' | jq .{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::<テストバケット名>/*"
}
]
}3. BPA 組み合わせ検証
ACL 経路のバケットレベル BPA(BlockPublicAcls, IgnorePublicAcls)は true に固定し、ポリシー経路の 2 設定(BlockPublicPolicy, RestrictPublicBuckets)の組み合わせを変えて検証する。パターン 1〜4 はバケットレベル BPA を操作し、パターン 5 はアカウントレベル BPA を操作する。
パターン 1: 両方 false(BPA 両方無効の基準状態)
aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=false,RestrictPublicBuckets=false \
--region ap-northeast-1
(出力なし)aws s3api get-public-access-block \
--bucket <テストバケット名> \
--region ap-northeast-1{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": false,
"RestrictPublicBuckets": false
}
}Config ルール手動トリガー(S3.2)
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)Config 評価結果の確認(S3.2)
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "NON_COMPLIANT"
}
]Config ルール手動トリガー(S3.3)
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)Config 評価結果の確認(S3.3)
aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "NON_COMPLIANT"
}
]バケットレベル BPA のポリシー経路が両方 false のため、バケットポリシーのパブリック読み取り・書き込みがそのまま評価され、S3.2・S3.3 ともに NON_COMPLIANT。他のパターンとの比較の出発点とする。
パターン 2: RestrictPublicBuckets のみ true
aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=false,RestrictPublicBuckets=true \
--region ap-northeast-1
(出力なし)aws s3api get-public-access-block \
--bucket <テストバケット名> \
--region ap-northeast-1{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": false,
"RestrictPublicBuckets": true
}
}Config ルール手動トリガー + 評価結果の確認(S3.2, S3.3)
パターン 1 と同じコマンドを実行する。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]S3.2: COMPLIANT / S3.3: COMPLIANT
RestrictPublicBuckets=true だけで「restricts public policies」と判定され、バケットポリシーの内容に関わらず COMPLIANT。
パターン 3: BlockPublicPolicy のみ true
BlockPublicPolicy=true にすると新規のパブリックポリシー設定がブロックされるが、既に設定済みのポリシーには影響しない。
aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=false \
--region ap-northeast-1
(出力なし)aws s3api get-public-access-block \
--bucket <テストバケット名> \
--region ap-northeast-1{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": false
}
}Config ルール手動トリガー + 評価結果の確認(S3.2, S3.3)
パターン 1 と同じコマンドを実行する。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]S3.2: COMPLIANT / S3.3: COMPLIANT
BlockPublicPolicy=true は新規パブリックポリシーの設定を予防するだけで既存ポリシーは撤去しない。にもかかわらず Config ルールは「restricts public policies の条件を満たす」と解釈し COMPLIANT 判定する。このため下記の callout のとおり、Security Hub 上は COMPLIANT でも実際にはパブリックアクセスが継続する状態になる。
BlockPublicPolicy=true, RestrictPublicBuckets=false)は Security Hub 上は COMPLIANT と判定されるが、既存のパブリックポリシーは依然として有効でパブリックアクセスが継続する。詳細と推奨設定は本ページ前半の Security Hub が COMPLIANT でも実際にはパブリックアクセスが継続するケース を参照。パターン 4: 両方 true
aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true \
--region ap-northeast-1
(出力なし)aws s3api get-public-access-block \
--bucket <テストバケット名> \
--region ap-northeast-1{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}Config ルール手動トリガー + 評価結果の確認(S3.2, S3.3)
パターン 1 と同じコマンドを実行する。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]S3.2: COMPLIANT / S3.3: COMPLIANT
両方 true のため BlockPublicPolicy が新規パブリックポリシーをブロックし、RestrictPublicBuckets が既存パブリックポリシーの効果を無効化する。この組み合わせが推奨設定。
パターン 5: アカウントレベル BPA(バケットレベル全無効)
バケットレベル BPA を全無効にした状態で、アカウントレベル BPA のポリシー経路 2 設定を有効化する。
バケットレベル BPA を全無効化
aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=false,RestrictPublicBuckets=false \
--region ap-northeast-1
(出力なし)アカウントレベル BPA を有効化
aws s3control put-public-access-block \
--account-id <アカウント ID> \
--public-access-block-configuration \
BlockPublicAcls=false,IgnorePublicAcls=false,BlockPublicPolicy=true,RestrictPublicBuckets=true \
--region ap-northeast-1
(出力なし)アカウントレベル BPA の確認
aws s3control get-public-access-block \
--account-id <アカウント ID> \
--region ap-northeast-1{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": false,
"IgnorePublicAcls": false,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}Config ルール手動トリガー + 評価結果の確認(S3.2, S3.3)
パターン 1 と同じコマンドを実行する。
aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice start-config-rules-evaluation \
--config-rule-names securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--region ap-northeast-1
(出力なし)aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-read-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]aws configservice get-compliance-details-by-config-rule \
--config-rule-name securityhub-s3-bucket-public-write-prohibited-<サフィックス> \
--query 'EvaluationResults[?EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId==`<テストバケット名>`].{ResourceId:EvaluationResultIdentifier.EvaluationResultQualifier.ResourceId,ComplianceType:ComplianceType}' \
--region ap-northeast-1[
{
"ResourceId": "<テストバケット名>",
"ComplianceType": "COMPLIANT"
}
]S3.2: COMPLIANT / S3.3: COMPLIANT
バケットレベル BPA が全無効でも、アカウントレベル BPA のポリシー経路が有効であれば COMPLIANT。Config ルールはアカウントレベル BPA も評価対象に含める。
アカウントレベル BPA を削除
aws s3control delete-public-access-block \
--account-id <アカウント ID> \
--region ap-northeast-1
(出力なし)4. クリーンアップ
aws s3api delete-bucket-policy \
--bucket <テストバケット名> \
--region ap-northeast-1
(出力なし)aws s3api put-public-access-block \
--bucket <テストバケット名> \
--public-access-block-configuration \
BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true \
--region ap-northeast-1
(出力なし)aws s3api delete-bucket \
--bucket <テストバケット名> \
--region ap-northeast-1
(出力なし)