

# 混乱する代理問題
<a name="confused-deputy"></a>

混乱した代理問題は、アクションを実行する許可を持たないエンティティが、より特権のあるエンティティにアクションを実行するように強制できるセキュリティの問題です。これを防ぐために、サードパーティー (*クロスアカウント*) や 他の AWS サービス (*クロスサービス*)に対して、お客様のアカウント内のリソースへのアクセス権を提供してしまった場合に、お客様のアカウントの保護に役立つツールを AWS が提供します。

お客様の AWS リソースへのアクセス権をサードパーティーに付与 (委任) することが必要になる場合があります。例えば、Example Corp という第三者企業を雇って、コストを最適化するためにお客様の AWS アカウント をモニタリングする業務を依頼することにします。Example Corp がお客様の毎日の支出を追跡するには、お客様の AWS リソースにアクセスする必要があります。また、Example Corp は他の顧客について他の多くの AWS アカウント をモニタリングしています。IAM ロールを使用して AWS アカウント と Example Corp アカウントと間の信頼関係を確立できます。このシナリオで重要なのは、オプションの識別子としての*外部 ID* です。この ID を IAM ロールの信頼ポリシーで使用することで、ロールを引き受けることができるユーザーを指定できます。外部 ID の最も重要な機能は、混乱した代理問題の防止と対処です。

一部の AWS サービス (呼び出し元サービス) は、AWS サービスプリンシパルを使用して、他の AWS サービス (呼び出し先サービス) から AWS リソースにアクセスします。これらのサービスインタラクションの一部では、別の AWS アカウント で呼び出し先サービスからリソースと通信するように呼び出し元サービスを設定できます。これの例としては、別の AWS アカウント にある中央 Amazon S3 バケットに書き込むように AWS CloudTrail を設定することが挙げられます。呼び出し元のサービスである CloudTrail には、`cloudtrail.amazonaws.com` の allow ステートメントを追加することで、S3 バケットのポリシーを使用する S3 バケットへのアクセスが付与されます。

呼び出し元のサービスの AWS サービスプリンシパルが呼び出し先のサービスからリソースにアクセスしている場合、呼び出し先のサービスのリソースポリシーは、呼び出し元のサービスを設定したアクターではなく、AWS サービスプリンシパルのみを承認します。例えば、条件なしで CloudTrail サービスプリンシパルを信頼する S3 バケットは、信頼された管理者が設定した AWS アカウント から CloudTrail ログを受信できますが、Amazon S3 バケットの名前がわかっている場合は、AWS アカウント 内の不正なアクターから CloudTrail ログを受信することもできます。

混乱した代理問題は、アクターが AWS サービスのサービスプリンシパルの信頼を使用して、アクセスすることを意図していないリソースにアクセスする場合に発生します。

## クロスアカウントでの混乱した代理
<a name="mitigate-confused-deputy"></a>

次の図は、クロスアカウントでの「混乱した代理」問題を示しています。

![「混乱した代理」問題の説明](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/images/confuseddeputyproblem2.png)


このシナリオでは、次のことを前提としています。
+ **AWS1** はあなたの AWS アカウント。
+ **AWS1:ExampleRole** は、お客様のアカウントのロールである。このロールの信頼ポリシーは、Example Corp の AWS アカウントを、ロールを引き受けることができるアカウントとして指定することによって、Example Corp を信頼しています。

次の状況が発生します。

1. お客様は、Example Corp のサービスの使用を開始するとき、**AWS1:ExampleRole** の ARN を Example Corp に提供します。

1. Example Corp はそのロールの ARN を使用して、お客様の AWS アカウント のリソースにアクセスするために必要な一時的なセキュリティ認証情報を入手します。この方法では、お客様に代わって操作を実行できる "代理" として Example Corp を信頼します。

1. 別の AWS ユーザーも Example Corp のサービスを利用し始め、このユーザーも **AWS1:ExampleRole** の ARN を Example Corp が使用できるように提供するとします。この別のユーザーは、秘密ではない **AWS1:ExampleRole** を知った、または推測した可能性があります。

1. その別のユーザーが Example Corp に自分のアカウントの AWS リソース (そう自称しているリソース) へのアクセスを依頼すると、Example Corp は **AWS1:ExampleRole** を使用してお客様のアカウントのリソースにアクセスします。

このようにして、その別のユーザーはお客様のリソースに不正にアクセスできます。Example Corp は、この別のユーザーによって操られ、無意識にお客様のリソースにアクセスしたため、"混乱した代理" になります。

Example Corp は、ロールの信頼ポリシーに `ExternalId` の条件の確認を含めることを必須とすることで、「混乱した代理」問題に対応できます。Example Corp は、顧客ごとに一意の `ExternalId` 値を生成して、ロールを引き受けるリクエストでその値を使用します。`ExternalId` 値は、Example Corp の顧客の間で一意でなければならず、Example Corp の顧客ではなく、Example Corp によって管理されます。そのため、外部 ID は Example Corp から取得するものであり、自分では用意できません。これにより、Example Corp が混乱した代理人になることを防ぎ、別のアカウントの AWS リソースへのアクセスを許可してしまうことを防ぎます。

このシナリオでは、Example Corp がお客様に割り当てた一意の ID は 12345 であり、もう一方のお客様に割り当てた ID は 67890 であるとします。これらの ID は、このシナリオで使用することのみを目的としているため、簡略化されています。通常、これらの ID は GUID です。これらの ID が Example Corp の顧客の間で一意であることを考慮すると、これらの値を外部 ID として使用することは賢明です。

Example Corp はお客様に 12345 という外部 ID 値を提供します。お客様は、`Condition` 値が 12345 であることを必須とする以下のような [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-sts](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_iam-condition-keys.html#condition-keys-sts) 要素をロールの信頼ポリシーに追加する必要があります。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": {
    "Effect": "Allow",
    "Principal": {
      "AWS": "{{Example Corp's AWS Account ID}}"
    },
    "Action": "sts:AssumeRole",
    "Condition": {
      "StringEquals": {
        "sts:ExternalId": "12345"
      }
    }
  }
}
```

------

このポリシーの Condition 要素により、AssumeRole API 呼び出しに 12345 という外部 ID 値が含まれている場合にのみ Example Corp はロールを引き受けることができます。Example Corp は、顧客に代わってロールを引き受けるたびに、その顧客の外部 ID 値を AssumeRole 呼び出しに含めます。別の顧客がお客様の ARN を Example Corp に提供した場合でも、Example Corp が AWS へのリクエストに含める外部 ID を顧客がコントロールすることはできません。これにより、権限のない顧客がお客様のリソースにアクセスすることを防止できます。

次の図は、このプロセスを示したものです。

![「混乱した代理」問題を解消する方法](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/images/confuseddeputymitigation2.png)


1. 前述と同様に、お客様は、Example Corp のサービスを利用し始めるとき、**AWS1:ExampleRole** の ARN を Example Corp に提供します。

1.  Example Corp がそのロールの ARN を使用して **AWS1:ExampleRole** ロールを引き受けるとき、Example Corp は AssumeRole API コールにお客様の外部 ID (12345) を含めます。この外部 ID はロールの信頼ポリシーと一致するため、AssumeRole API 呼び出しは正常に実行され、Example Corp はお客様の AWS アカウント のリソースにアクセスするための一時的なセキュリティ認証情報を取得します。

1. 別の AWS ユーザーも Example Corp のサービスを利用し始め、先ほどと同様、このユーザーも **AWS1:ExampleRole** の ARN を Example Corp が使用できるように提供するとします。

1. しかし、今回は、Example Corp が **AWS1:ExampleRole** ロールを引き受けるとき、もう一方のお客様に関連付けられている外部 ID (67890) が提供されます。その別の顧客がこの ID を変更することはできません。Example Corp がこれを行うのは、ロールを使用するリクエストがもう一方のお客様から来たからであり、67890 は Example Corp が業務を遂行する環境を示すからです。お客様は自身の外部 ID (12345) を使用する条件を **AWS1:ExampleRole** の信頼ポリシーに追加したため、AssumeRole API コールは失敗します。別の顧客がお客様のアカウントのリソースに不正にアクセスすることが防止されます (図の赤色の「X」で示しています)。

外部 ID により、Example Corp が他の顧客によって操られ、無意識にお客様のリソースにアクセスすることを防止します。

## サービス間の混乱した代理の防止
<a name="cross-service-confused-deputy-prevention"></a>

次の図は、CloudTrail と Amazon S3 のインタラクションの例を使用して、サービス間の混乱した代理問題を示しています。ここでは、権限のないアクターが、アクセス権が付与されていない Amazon S3 バケットに CloudTrail ログを書き込みます。

![権限のないアクターには、CloudTrail サービスプリンシパルを使用して、別のアカウントの Amazon S3 バケットへのアクセス権が付与されます。](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/images/cross-service-confused-deputy1.png)


権限のないアクターが AWS プリンシパルの信頼を使用してリソースにアクセスできないように保護するために、AWS サービスプリンシパルには、代理で動作する AWS リソース、AWS アカウント、AWS 組織に関する情報があります。

この情報は、リソースポリシーで使用できるグローバル条件キー値、または AWS サービスプリンシパルによって行われたリクエストのリソースコントロールポリシーで使用できます。AWS サービスプリンシパルにリソースの 1 つにアクセスするためのアクセス許可が付与されている場合は、リソースポリシーで [aws:SourceArn](reference_policies_condition-keys.md#condition-keys-sourcearn)、[aws:SourceAccount](reference_policies_condition-keys.md#condition-keys-sourceaccount)、[aws:SourceOrgID](reference_policies_condition-keys.md#condition-keys-sourceorgid)、または [aws:SourceOrgPaths](reference_policies_condition-keys.md#condition-keys-sourceorgpaths) を使用することをお勧めします。これらの条件キーを使用すると、リソースポリシー、または リソースにアクセスする AWS サービスプリンシパルが、AWS リソース、AWS アカウント、または想定する AWS Organizations の代理で実行しているリソースコントロールポリシーでテストできます。
+ `aws:SourceArn` を使用して、AWS サービスプリンシパルが、特定の AWS CloudTrail 証跡や AppStream フリートなどの特定のリソースの代理としてリソースにアクセスできるようにします。
+ `aws:SourceAccount` を使用して、AWS サービスプリンシパルが特定の AWS アカウント の代理としてリソースにアクセスできるようにします。
+ `aws:SourceOrgID` を使用して、AWS サービスプリンシパルが特定の AWS Organizations の代理としてリソースにアクセスできるようにします。
+ `aws:SourceOrgPaths` を使用して、AWS サービスプリンシパルが特定の AWS Organizations パスの代理としてリソースにアクセスできるようにします。

次の図は、リソースが `aws:SourceAccount` グローバル条件コンテキストキーで設定されていて、別のアカウントの不正なアクターがアクセスすることを意図していない AWS リソースにアクセスしようとする、サービス間の混乱した代理シナリオを示しています。

![不正なアクターは、CloudTrail サービスプリンシパルを使用して、別のアカウントの Amazon S3 バケットへのアクセスを拒否されます。](http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/images/cross-service-confused-deputy2.png)


ポリシーで `aws:SourceArn`、`aws:SourceAccount`、`aws:SourceOrgID`、および `aws:SourceOrgPaths` グローバル条件キーを使用すると、サービスプリンシパルがユーザーの代理としてリソースにアクセスしていることを確認できます。これらの条件キーは、いずれかのリソースへのアクセスが AWS サービスプリンシパルに付与されるたびに使用することをお勧めします。

**注記**  
一部の AWS のサービス インタラクションには、ユーザーによるリソースへのアクセスをテストするサービス間の混乱した代理問題から保護するのに役立つ追加のコントロールがあります。例えば、KMS キー付与が AWS のサービス に発行されると、AWS KMS はリソースに関連付けられた暗号化コンテキストとキーのグラントを使用して、サービス間の混乱した代理問題から保護します。  
サービス間の混乱した代理リスクを回避するのに役立つサービス固有のメカニズム、および `aws:SourceArn`、`aws:SourceAccount`、`aws:SourceOrgID`、`aws:SourceOrgPaths` がサポートされるかどうかの詳細については、使用するサービスのドキュメントを参照してください。

## リソースベースのポリシーによるサービス間の混乱した代理保護
<a name="cross-service-confused-deputy-prevention-resource"></a>

次のポリシー例では、サービスプリンシパル AWS アカウント が 111122223333 に代わって動作している場合にのみ、サービスプリンシパル `cloudtrail.amazonaws.com` に Amazon S3 バケット arn:aws:s3:::amzn-s3-demo-bucket1 へのアクセスを許可します。

------
#### [ JSON ]

****  

```
{
    "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"
                }
            }
        }
    ]
}
```

------

このバケットポリシーの例では、`aws:SourceArn` でフリート ARN を指定することで、指定された Amazon AppStream フリートに代わって動作している場合にのみ、s3://amzn-s3-demo-bucket2 内の powershell スクリプト examplefile.psh へのアクセスをサービスプリンシパル `appstream.amazonaws.com` に許可します。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": [
                    "appstream.amazonaws.com"
                ]
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::{{amzn-s3-demo-bucket2/examplefile.psh}}",
            "Condition": {
                "ArnEquals": {
                    "aws:SourceArn": "arn:aws:appstream:us-east-1:{{111122223333}}:{{fleet/ExampleFleetName}}"
                } 
            }
        }
    ]
}
```

------

## リソースコントロールポリシーによるサービス間の混乱した代理保護
<a name="cross-service-confused-deputy-prevention-resource-control"></a>

リソースコントロールポリシー (RCP) を使用して、サポートされている AWS のサービス のリソースにサービス間の混乱した代理コントロールを適用できます。RCP を使用すると、サービス間の混乱した代理コントロールをリソースに一元的に適用できます。特定のリソースベースポリシーにステートメントを追加しなくても、組織内の AWS Organizations、組織単位 (OU)、または AWS アカウント にアタッチされた RCP で、`aws:SourceOrgId` や `aws:SourceOrgPaths` のような条件キーを使用できます。RPC とサポートされているサービスに関する詳細については、「*AWS Organizations ユーザーガイド*」の「[リソースコントロールポリシー (RCPs)](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_policies_rcps.html)」を参照してください。

次の RCP の例では、`aws:SourceOrgID` が o-ExampleOrg に相当する場合、メンバーアカウントの Amazon S3 バケットへの AWS サービスプリンシパルアクセスを拒否します。`SourceOrgID` が o-ExampleOrg に等しい AWS のサービス プリンシパルを許可するには、対応する許可が S3 バケットのリソースベースのポリシーに存在する必要があります

このポリシーは、`aws:SourceAccount` キーが存在するサービスプリンシパル (`"Bool": {"aws:PrincipalIsAWSService": "true"}`) によるリクエストに対してのみ、コントロールを適用します (`"Null": {"aws:SourceAccount": "false"}`)。これにより、この条件キーの使用を必要としないサービス統合とプリンシパルによる呼び出しは影響を受けません。`aws:SourceAccount` 条件キーがリクエストコンテキストに存在する場合、Null 条件は true に評価され、`aws:SourceOrgID` が強制適用されます。リクエストが組織に属さないアカウントからのものである場合でもコントロールが適用されるように、Null 条件演算子では `aws:SourceOrgID` ではなく `aws:SourceAccount` が使用されます。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "RCPEnforceConfusedDeputyProtectionForS3",
      "Effect": "Deny",
      "Principal": "*",
      "Action": [
        "s3:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEqualsIfExists": {
          "aws:SourceOrgID": "{{o-ExampleOrg}}"
        },
        "Null": {
          "aws:SourceAccount": "false"
        },
        "Bool": {
          "aws:PrincipalIsAWSService": "true"
        }
      }
    }
  ]
}
```

------