ENGINEER BLOG ENGINEER BLOG
  • 公開日
  • 最終更新日

【サービス間の混乱した代理の防止】を検証して読み解く

この記事を共有する

目次

はじめに

AWS 環境のセキュリティ管理を検討したとき、「混乱した代理」問題¹ を読んだことはありませんか?
図による例示もありますが、筆者は理解に苦労して「混乱した代理」問題を混乱しながら読むことになりました。
そこで図の内容を実際に検証し、その仕組みを読み解くことにしました。

本記事では、「混乱した代理」問題の項目「サービス間の混乱した代理の防止」を読み解いていきます。

以下、固有情報は筆者が {} で囲って匿名化しています。

1.不正なアカウントによる、アクセス権限のない S3 バケットへの CloudTrail ログの書き込み

「サービス間の混乱した代理の防止」¹ より引用した以下図について、順序立てて検証します。

1-1.Admin bucket の作成

以下文章¹の確認です。

Admin creates bucket, adds bucket policy to trust the CloudTrail service principal with no condition

管理者アカウント「111122223333」に S3 バケット「Admin bucket」を作成します。
図の例に従い、条件(Condition)なしで Principal で CloudTrail サービスを許可するバケットポリシーを追加します。

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::{Admin bucket name}"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{Admin bucket name}/*"
        }
    ]
}

補足:"s3:GetBucketAcl" の許可について

図に記載された以下バケットポリシー¹には、"s3:GetBucketAcl" の許可は記載されていません。

Bucket Policy Statement: 
{
"Effect": "Allow",
"Principal": {
    "Service": "cloudtrail.amazonaws.com"
    },
"Action": "s3:PutObject",
"Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
}

ただし、「CloudTrail の Amazon S3 バケットポリシー」² に記載のとおり、CloudTrail がログファイルを書き込む際は"s3:GetBucketAcl"の許可が必要です。
実際、バケットポリシーに"s3:GetBucketAcl"の許可を追加しなかった場合、CloudTrail の証跡は S3 バケットへのアクセスが拒否されました。
そのため、検証ではバケットポリシーに"s3:GetBucketAcl"の許可を追加しています。

1-2.管理者アカウントで CloudTrail を設定

以下文章¹の確認です。

Admin configures CloudTrail to write to their S3 bucket

管理者アカウントで CloudTrail の証跡を設定して、ストレージに「Admin bucket」を指定します。
CloudTrail の証跡を設定すると S3 バケットに自動でバケットポリシーが追記されるため、「Admin bucket」に追記されたバケットポリシーを削除します。

  • バケットポリシーが追記された状態³

クリックして展開

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::{Admin bucket name}"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{Admin bucket name}/*"
        },
        {
            "Sid": "AWSCloudTrailAclCheck20150319-xxxxxxxxxxxxxx",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::{Admin bucket name}",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudtrail:{Region}:{Account}:trail/{Trail name}"
                }
            }
        },
        {
            "Sid": "AWSCloudTrailWrite20150319-xxxxxxxxxxxxxx",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{Admin bucket name}/AWSLogs/{Account}/*",
            "Condition": {
                "StringEquals": {
                    "AWS:SourceArn": "arn:aws:cloudtrail:{Region}:{Account}:trail/{Trail name}",
                    "s3:x-amz-acl": "bucket-owner-full-control"
                }
            }
        }
    ]
}

  • 追記されたバケットポリシーを削除

クリックして展開

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::{Admin bucket name}"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{Admin bucket name}/*"
        }
    ]
}

1-3.管理者アカウントの CloudTrail ログを書き込み

以下文章¹の確認です。

CloudTrail uses a service principal to write CloudTrail logs to the bucket the admin created from account 111122223333

管理者アカウントで適当な操作(サブネットの新規作成など)を実施してから、CloudTrail によりログファイルが「Admin bucket」に書き込まれることを待ちます。
「ログファイルの表示」⁴ 記載の以下の通り、操作から平均 5 分程度でログファイルを書き込みます。

CloudTrail は、通常、API コールから平均 5 分以内にログを配信します。この時間は保証されません。

1-4.「Admin bucket」への書き込みを確認

以下文章¹の確認です。

Access is granted to the service principal acting on behalf of account 111122223333

「Admin bucket」のオブジェクトを確認して、管理者アカウントの CloudTrail ログファイルが書き込まれたことを確認できました。
「Admin bucket」はバケットポリシーの Principal で CloudTrail サービスを許可しているため、書き込みが可能です。

1-5.不正なアカウントで CloudTrail を設定

以下文章¹の確認です。

An Unauthorized Actor configures CloudTrail in their account to target the bucket the admin created

不正なアカウントで CloudTrail の証跡を設定して、ストレージに「Admin bucket」を指定します。
S3 バケットを指定するときに必要な情報はバケット名のみであり、S3 バケットを保有するアカウント ID を知らなくても設定できます。
他アカウントの S3 バケットをストレージに指定して証跡を作成すると、以下のメッセージ⁵が表示されます。

We can not fetch current bucket access policy for bucket {Admin bucket name}, thus we did not try to update it. Please check the bucket policy manually if need

1-6.不正なアカウントの CloudTrail ログを書き込み

以下文章¹の確認です。

CloudTrail uses a service principal to write CloudTrail logs from account 444455556666 to the bucket the admin created

不正なアカウントで適当な操作を実施してから、CloudTrail によりログファイルが「Admin bucket」に書き込まれることを待ちます。

1-7.「Admin bucket」への書き込みを確認

以下文章¹の確認です。

Access is granted to the service principal acting on behalf of account 444455556666

「Admin bucket」のオブジェクトを確認して、不正なアカウントの CloudTrail ログファイルが書き込まれたことを確認できました。
「Admin bucket」はバケットポリシーにて条件(Condition)なしで Principal で CloudTrail サービスを許可しているため、不正なアカウントからの書き込みが可能です。

不正なアカウントからの保護について

「1.不正なアカウントによる、アクセス権限のないS3バケットへの CloudTrail ログの書き込み」 では Service Principal による信頼を使用した、許可されていないリソースへのアクセスの発生が例示されています。
このように Service Principal にリソースへのアクセス権限を付与する場合、リソースポリシーに以下の条件キーを使用することが推奨¹されます。

・aws:SourceArn を使用して、AWS サービスプリンシパルが、特定の AWS CloudTrail 証跡や AppStream フリートなどの特定のリソースの代理としてリソースにアクセスできるようにします。
・aws:SourceAccount を使用して、AWS サービスプリンシパルが特定の AWS アカウント の代理としてリソースにアクセスできるようにします。
・aws:SourceOrgID を使用して、AWS サービスプリンシパルが特定の AWS Organizations の代理としてリソースにアクセスできるようにします。
・aws:SourceOrgPaths を使用して、AWS サービスプリンシパルが特定の AWS Organizations パスの代理としてリソースにアクセスできるようにします。

次の項にて、"aws:SourceAccount"を使用した場合の例示を説明します。

2.条件(Condition)"aws:SourceAccount"を設定したとき、不正なアカウントのアクセスはどうなるか

「サービス間の混乱した代理の防止」¹ より引用した以下図について、順序立てて検証します。

2-1.Admin bucket のバケットポリシーを更新

以下文章¹の確認です。

Admin creates bucket, adds bucket policy to trust the CloudTrail service principal only when it is acting on behalf of their account

検証では挙動を比較するため、新規に S3 バケットを作成せず、「1-1.Admin bucket の作成」で作成した「Admin bucket」のバケットポリシーを修正します。
図の例に従い、"s3:PutObject"の許可について条件(Condition)に管理者アカウントを指定します。

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "AWSCloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::{Admin bucket name}"
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "cloudtrail.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::{Admin bucket name}/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "{管理者アカウント ID}"
                }
            }
        }
    ]
}

2-2.管理者アカウントで CloudTrail を設定

以下文章¹の確認です。

Admin configures CloudTrail to write to their S3 bucket

「1-2.管理者アカウントで CloudTrail を設定」で作成した証跡を使用するため、本検証では読み飛ばします。

2-3.管理者アカウントの CloudTrail ログを書き込み

以下文章¹の確認です。

CloudTrail uses a service principal to write CloudTrail logs to the bucket the admin created from account 111122223333

管理者アカウントで適当な操作を実施してから、CloudTrail によりログファイルが「Admin bucket」に書き込まれることを待ちます。

2-4.「Admin bucket」への書き込みを確認

以下文章¹の確認です。

Access is granted to the service principal acting on behalf of account 111122223333

「Admin bucket」のオブジェクトを確認して、管理者アカウントの CloudTrail ログファイルが書き込まれたことを確認できました。
「Admin bucket」はバケットポリシーにて、Principal で CloudTrail サービスを許可しています。
さらに条件(Condition)のアカウント ID(aws:SourceAccount)と一致(StringEquals)しているため、書き込みが可能です。

2-5.不正なアカウントで CloudTrail を設定

以下文章¹の確認です。

An Unauthorized Actor configures CloudTrail in their account to target the bucket the admin created

「1-5.不正なアカウントで CloudTrail を設定」で作成した証跡を使用するため、本件章では読み飛ばします。

2-6.不正なアカウントの CloudTrail ログを書き込み不可

以下文章¹の確認です。

CloudTrail is denied access to write to the S3 bucket on behalf of account 444455556666 because the bucket policy does not allow it

不正なアカウントで適当な操作を実施してから、CloudTrail によりログファイルが「Admin bucket」に書き込まれることを待ちます。
ただし、バケットポリシーによって拒否されるため、ログは書き込まれません。

2-7.「Admin bucket」への書き込み拒否を確認

以下文章¹の確認です。

Access is denied to the service principal acting on behalf of account 444455556666

不正なアカウントに作成した CloudTrail の証跡を確認すると、以下のようにステータス⁵が「バケットアクセスが拒否されました」と表示されています。

「Admin bucket」のバケットポリシーに追記した条件(Condition)に"aws:SourceAccount"を指定したことで、管理者アカウント以外のアクセスが拒否されました。

まとめ

本記事では、「混乱した代理」問題の項目「サービス間の混乱した代理の防止」を読み解きました。
図の例示では、以下を確認しています。

  • S3 バケットに対して、条件(Condition)なしで Principal で CloudTrail サービスを許可するバケットポリシーを追加すると、意図しない AWS アカウントの CloudTrail サービスからのアクセスも許可されてしまう。
  • バケットポリシーに条件(Condition)"aws:SourceAccount"を追加すると、意図した AWS アカウントの CloudTrail サービスからのみアクセスが許可される。

重要な点として、Service Principal にリソースへのアクセス権限を付与する場合、リソースポリシーに以下の条件キーを使用することが推奨¹されます。

・aws:SourceArn を使用して、AWS サービスプリンシパルが、特定の AWS CloudTrail 証跡や AppStream フリートなどの特定のリソースの代理としてリソースにアクセスできるようにします。
・aws:SourceAccount を使用して、AWS サービスプリンシパルが特定の AWS アカウント の代理としてリソースにアクセスできるようにします。
・aws:SourceOrgID を使用して、AWS サービスプリンシパルが特定の AWS Organizations の代理としてリソースにアクセスできるようにします。
・aws:SourceOrgPaths を使用して、AWS サービスプリンシパルが特定の AWS Organizations パスの代理としてリソースにアクセスできるようにします。

本記事が少しでもお役に立てば幸いです。

おまけ

リソースベースのポリシーによるサービス間の混乱した代理保護

「リソースベースのポリシーによるサービス間の混乱した代理保護」¹では、CloudTrail のアクセスを許可する S3 バケットポリシーについて、さらなる制限を例示しています。
以下が引用したポリシー例¹です。

クリックして展開

{
    "Version":"2012-10-17",              
    "Statement": [
        {
            "Sid": "CloudTrailAclCheck",
            "Effect": "Allow",
            "Principal": {"Service": "cloudtrail.amazonaws.com"},
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "111122223333"
                }
            }
        },
        {
            "Sid": "AWSCloudTrailWrite",
            "Effect": "Allow",
            "Principal": {"Service": "cloudtrail.amazonaws.com"},
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/[optionalPrefix]/Logs/myAccountID/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "111122223333"
                }
            }
        }
    ]
}

"s3:GetBucketAcl"

条件(Condition)"aws:SourceAccount"を追加しています。

"s3:PutObject"

Resource 要素にプレフィックスまで記載しています。
CloudTrail ログファイルが S3 バケットに保存されるとき、プレフィックスにアカウント ID が含まれます。
そのため Resource 要素の S3 バケットのパスにアカウント ID を含めることで、他アカウントの CloudTrail ログファイルが保存されることを防ぎます。
注意点として、ポリシー例のプレフィックスは「Logs」と記載されていますが、正確には「AWSLogs」です。

CloudTrail の Amazon S3 バケットポリシー

本筋から外れますが、CloudTrail のアクセスを許可する S3 バケットポリシーを設定する場合、本記事に記載したポリシー例は不十分です。
ユーザーガイド 「CloudTrail の Amazon S3 バケットポリシー」² に記載がある、"aws:SourceArn"や"s3:x-amz-acl"の条件(Condition)を記載します。
ただ CloudTrail の証跡を設定すると S3 バケットに自動でバケットポリシーが追記されるため、意識して設定することは少ないと思います。

参考文献

¹ "「混乱した代理」問題 - AWS Identity and Access Management". AWS Documentation. https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/confused-deputy.html, (参照 2025-12-05)
² "CloudTrail の Amazon S3 バケットポリシー - AWS CloudTrail". AWS Documentation. https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html, (参照 2025-12-05)
³ "S3 バケット | S3 | ap-northeast-1". Amazon Web Services. https://ap-northeast-1.console.aws.amazon.com/s3/buckets/{●●●}?region=ap-northeast-1&tab=permissions, (参照 2025-12-05)
⁴ "ログファイルの表示 - AWS CloudTrail". AWS Documentation. https://docs.aws.amazon.com/ja_jp/awscloudtrail/latest/userguide/tutorial-trail-logs.html, (参照 2025-12-06)
⁵ "Trails | CloudTrail | ap-northeast-1". Amazon Web Services. https://ap-northeast-1.console.aws.amazon.com/cloudtrailv2/home?region=ap-northeast-1#/trails, (参照 2025-12-05)

この記事は私が書きました

Hirano

記事一覧

AWSの知見を身につけるため、一大決心でP&Sに入社しました。 目標はシステム改善に大きく貢献できるエンジニアになることです。 簡単な内容であっても自身が戸惑った点を投稿することで、同じ苦労をしている方の助けになれば嬉しいです!

Hirano

この記事を共有する

クラウドのご相談

CONTACT

クラウド導入や運用でお悩みの方は、お気軽にご相談ください。
専門家がサポートします。

サービス資料ダウンロード

DOWNLOAD

ビジネスをクラウドで加速させる準備はできていますか?
今すぐサービス資料をダウンロードして、詳細をご確認ください。