
# 混淆代理问题
混淆代理问题（Confused Deputy Problem）是一种安全漏洞，指无权限执行某项操作的主体通过操纵高权限主体间接完成该操作。为防止此类风险，华为云提供了多种措施来帮助您安全地向第三方（跨账号）或其他华为云服务（跨服务）开放账号资源的访问权限。
在委托第三方访问的场景中，您可能聘请第三方公司监控您的华为云账号以优化成本。在该场景中，第三方公司需要访问您的华为云账号，同时它可能还为其他客户监控着许多华为云账号，您可以使用IAM[信任委托](https://support.huaweicloud.com/usermanual-iam5/iam_01_0915.html)在您的华为云账号与第三方公司账号之间建立信任关系。在该场景中防范混淆代理一个关键要素是外部ID（External ID），这是一个可选项，您可以通过在信任委托的信任策略中使用它来指定谁能切换该委托。
在委托云服务访问的场景中，您可能会委托一些云服务来帮助您操作您账号中的资源。例如，由于业务需要，您创建了一个信任委托，将其信任关系配置为信任某一个云服务，并在该云服务的任务中配置了使用该信任委托；由于信任委托的URN不是秘密，若此时有攻击者也通过该云服务配置了任务，并且在任务配置中也使用了您的信任委托，此时该云服务就有错误使用您的信任委托的风险。为了解决这种风险场景，您应该在给云服务的信任委托中的信任策略中使用[g:SourceAccount]和[g:SourceUrn]条件键。
 #### 防止跨账号混淆代理
下图说明了跨账号混淆代理问题。
图1跨账号混淆代理问题   
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002401704293.png "点击放大")
在该场景中，账号A是您自己的账号，信任委托A是您账号创建的信任第三方公司的一个信任委托。因此，可以通过以下步骤产生混淆代理问题：
1. 在您使用第三方公司的服务时，您将信任委托A的URN提供给第三方公司。
2. 第三方公司使用该信任委托的URN获取临时安全凭证以访问您账号中的资源。
3. 另外一个账号B也开始使用第三方公司的服务，由于您的信任委托A的URN不是机密信息，账号B可能已经猜到了信任委托A的URN，并将该URN也提供给第三方公司使用。
4. 当账号B要求第三方公司访问（它声称的）其账号的资源时，第三方公司使用信任委托A的URN访问了您账号A中的资源。
上述流程讲述了其他账号对您的资源进行未授权访问的方式。由于账号B能够诱导第三方公司无意间操作您的资源，因此第三方公司现在是一个混淆代理。
您可以通过在账号A的信任委托的信任策略中添加sts:ExternalId条件键的方式来解决混淆代理问题。第三方公司可以为每个客户生成一个唯一的ExternalId值，并在其切换信任委托时传递该ExternalId值给[AssumeAgency API](https://support.huaweicloud.com/usermanual-iam5/iam_01_1237.html#iam_01_1237__section1787814409312)。假设第三方公司给您的ExternalId为123456，则您必须在账号A的信任委托的信任策略中添加该ExternalId，如下所示：
```
{
"Version": "5.0",
"Statement": [{
"Action": [
"sts:agencies:assume"
],
"Effect": "Allow",
"Principal": {
"IAM": [
"AccountA ID"
]
},
"Condition": {
"StringEquals": {
"sts:ExternalId": [
"123456"
]
}
}
}]
}
```
该信任策略中的Condition元素允许第三方公司在AssumeAgency API包含ExternalId为123456时能够成功调用，第三方公司需要确保，只要调用AssumeAgency API切换用户的信任委托，就始终会传递客户的ExternalId。这样，即使账号B向第三方公司提供您的信任委托A的URN，他也无法控制第三方公司在AssumeAgency API中传递的ExternalId。带有ExternalId的过程如下图所示：
图2带有ExternalId的过程   
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002401704941.png "点击放大")
1. 和之前一样，在您使用第三方公司的服务时，您将信任委托A的URN提供给第三方公司。
2. 第三方公司携带ExternalId调用AssumeAgency API，获取信任委托A的临时安全凭证以访问您账号中的资源。
3. 另外一个账号B也开始使用第三方公司的服务，并且也提供了您的信任委托A的URN给第三方公司使用。
4. 但是这一次，当账号B要求第三方公司访问（它声称的）其账号的资源时，第三方公司会携带与账号B关联的ExternalId（456789）去调用AssumeAgency API，由于您只将您自己ExternalId（123456）添加到了信任策略中，而并没有将账号B的ExternalId（456789）添加到信任策略中，因此使用您的信任委托A的URN调用AssumeAgency API将会失败。
 
#### 防止跨服务混淆代理
为了防止未经授权的账号利用云服务信任委托来访问您的华为云资源，华为云的服务主体提供了他们所代表的华为云账号、资源的信息，这些信息以全局条件键g:SourceAccount、g:SourceUrn的形式出现在请求上下文中，因此使用这两个条件键可以解决跨服务混淆代理问题。
例如：由于业务需要，您的账号A创建了一个信任委托A，并将其信任关系配置为信任云服务B，并在云服务B的任务中配置了使用该信任委托：
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002360756386.png "点击放大")
此时的信任策略如下：
```
{
"Version": "5.0",
"Statement": [{
"Action": [
"sts:agencies:assume"
],
"Effect": "Allow",
"Principal": {
"Service": [
"service.B"
]
}
}]
}
```
由于信任委托URN不是秘密，若此时攻击者账号C也通过服务B配置了任务，并且在任务中配置使用信任委托A，此时云服务B就有错误使用信任委托A的风险。接下来介绍如何使用g:SourceAccount、g:SourceUrn全局条件键解决该问题。
- **g:SourceAccount**
  g:SourceAccount表示云服务是为哪个账号获取临时凭证，当您在为服务B创建信任委托时增加了g:SourceAccount条件键，表明云服务B只允许为账号A发起调用切换信任委托A。如下所示，当攻击者账号C也向服务B触发请求时，IAM在鉴权时会校验该条件键，如果发现云服务是为其他账号发起的调用，则会拒绝该请求。
  ```
  {
  "Version": "5.0",
  "Statement": [{
  "Action": [
  "sts:agencies:assume"
  ],
  "Effect": "Allow",
  "Principal": {
  "Service": [
  "service.B"
  ]
  },
  "Condition": {
  "StringEquals": {
  "g:SourceAccount": [
  "AccountA ID"
  ]
  }
  }
  }]
  }
  ```
  

- **g:SourceUrn**
  g:SourceUrn表示云服务是为了哪个资源获取临时凭证，当您在为服务B创建信任委托时增加了g:SourceUrn条件键，表明云服务B只允许为指定资源发起调用切换信任委托A。如下所示，当攻击者账号C也向服务B触发请求时，IAM在鉴权时会校验该条件键，如果发现云服务是为了其他资源发起的调用，则会拒绝该请求。
  ```
  {
  "Version": "5.0",
  "Statement": [{
  "Action": [
  "sts:agencies:assume"
  ],
  "Effect": "Allow",
  "Principal": {
  "Service": [
  "service.B"
  ]
  },
  "Condition": {
  "StringEquals": {
  "g:SourceUrn": [
  "Specific Resource URN"
  ]
  }
  }
  }]
  }
  ```
  
 
