混乱する代理問題 - AWS Identity and Access Management

混乱する代理問題

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

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

AWS では、サービス間でのなりすましが、混乱した代理問題を生じさせることがあります。サービス間でのなりすましは、1 つのサービス (呼び出し元サービス) が、別のサービス (呼び出し対象サービス) を呼び出すときに発生する可能性があります。呼び出し元サービスは、本来ならアクセスすることが許可されるべきではない方法でその許可を使用して、別の顧客のリソースに対する処理を実行するように操作される場合があります。

クロスアカウントでの混乱した代理

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


                「混乱した代理」問題の説明

このシナリオでは、次のことを前提としています。

  • AWS1 はお客様の AWS アカウント ID です。

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

次の状況が発生します。

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

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

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

  4. その別のユーザーが 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 であることを必須とする以下のような sts:ExternalId 要素をロールの信頼ポリシーに追加する必要があります。

{ "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 を顧客がコントロールすることはできません。これにより、権限のない顧客がお客様のリソースにアクセスすることを防止できます。

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


                「混乱した代理」問題を解消する方法
  1. 前述と同様に、お客様は、Example Corp のサービスを利用し始めるとき、AWS1:ExampleRole の ARN を Example Corp に提供します。

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

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

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

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

サービス間の混乱した代理の防止

リソースベースのポリシー内では aws:SourceArn および aws:SourceAccount のグローバル条件コンテキストキーを使用して、サービスが持つ特定のリソースへのアクセス許可を制限することをお勧めします。クロスサービスのアクセスにリソースを 1 つだけ関連付けたい場合は、aws:SourceArn を使用します。クロスサービスが使用できるように、アカウント内の任意のリソースを関連づけたい場合は、aws:SourceAccount を使用します。

混乱した代理問題から保護するための最も効果的な方法は、リソースベースポリシー内のリソースの完全な ARN を指定しながら、グローバル条件コンテキストキー aws:SourceArn を使用することです。リソースの完全な ARN が不明な場合や、複数のリソースを指定する場合には、グローバル条件コンテキストキー aws:SourceArn で、ARN の未知部分を示すためにワイルドカード (*) を使用します。例えば、arn:aws:servicename:*:123456789012:* です。

aws:SourceArn の値に Amazon S3 バケット ARN などのアカウント ID が含まれていない場合は、両方のグローバル条件コンテキストキーを使用して、アクセス許可を制限する必要があります。

AWS Security Token Service のクロスサービスでの混乱した代理の防止

AWS の多くのサービスでは、ロールを使用して、ユーザーに代わって該当サービスが他のサービスのリソースにアクセスすることを許可する必要があります。サービスがお客様に代わってアクションを実行するために引き受けるロールは、サービスロールと呼ばれます。ロールには 2 つのポリシーが必要です。ロールを引き受けることができるプリンシパルを指定する、ロールの信頼ポリシーと、ロールで実行できる操作を指定する、アクセス許可ポリシーです。IAM においては、ロールの信頼ポリシーがリソースベースのポリシーの唯一のタイプです。その他の AWS サービスには、Amazon S3 バケットポリシーなどのリソースベースのポリシーがあります。

サービスがユーザーに代わってロールを引き受ける場合、サービスプリンシパルが sts:AssumeRole アクションを実行できるように、ロールの信頼ポリシーで許可されている必要があります。サービスが sts:AssumeRole を呼び出すとき、ロールのアクセス許可ポリシーで許可されているリソースに、サービスプリンシパルがアクセスするために使用する、一時的なセキュリティー認証情報のセットを、AWS STS が返します。アカウント内でサービスがロールを引き受ける場合は、ロール信頼ポリシーに aws:SourceAccount または aws:SourceArn のグローバル条件コンテキストキーを含めることで、期待するリソースによって生成されたリクエストのみに、ロールのアクセスを制限できます。

例えば、AWS Systems Manager Incident Manager の場合、お客様の代わりに Incident Manager が Systems Manager Automation ドキュメント を実行できるように、ロールを選択する必要があります。オートメーションドキュメントには、CloudWatch アラームまたは EventBridge イベントによって開始される、インシデントの自動化された応答プランを含めることができます。次のロール信頼ポリシーの例では、aws:SourceArn 条件キーを使用して、インシデントレコードの ARN をもとに、サービスロールへのアクセスを制限できます。応答プランリソース myresponseplan から作成されたインシデントレコードのみが、このロールを使用できます。

{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": { "Service": "ssm-incidents.amazonaws.com" }, "Action": "sts:AssumeRole", "Condition": { "ArnLike": { "aws:SourceArn": "arn:aws:ssm-incidents:*:111122223333:incident-record/myresponseplan/*" } } } }