其他 AWS 用户错误地能够访问我的 AWS SecretsManager 秘密值,这是用我的 AWS KMS CMK 加密的

问题描述

我使用我的 AWS KMS CMK 来加密和 AWS SecretsManager Secret,但我的同事可以看到密钥值!!

  • 我的 KMS CMK 政策规定我只能执行 kms:Decrypt
  • 我的同事(在我的 CMK 上没有这些权限)能够...
    • 打开 AWS 控制台到 SecretsManager >>>
    • 点击Retrieve Secret Value >>>
    • 看看我的秘密价值!

知道为什么吗?

技术细节:

我正在使用 AWS SAM CLI 来部署它。

这是我的 AWS SAM 模板:

AWstemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Parameters:
  SecretValue:
    Type: String
  KmsCmkId: 
    Type: String

Resources:
  MySecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      SecretString:
        Ref: SecretValue
      KmsKeyId: !Ref KmsCmkId

我用这个构建和部署它:

sam build ; sam deploy --guided --parameter-overrides SecretValue=ABC KmsCmkId=REDACTED

我迄今为止的调试:

  • 搜索serverfault.com,但基本上没有结果。我搜索了 Stack Overflow 只找到了一篇帖子,似乎是相关的,但问题没有阐明,解决方案不是我的情况:AWS KMS CMK encrypt and decrypt with symmetric and asymmetric

  • 我正在使用 对称 CMK,因为 SecretsManager 需要它。 (SecretsManager 不允许使用非对称 CMK 来加密秘密值。

  • 我确认单击 AWS SecretsManager 控制台中的 Retrieve Secret Value 按钮确实执行了带有 secretsmanager:GetSecretValue 的 API 调用

  • AWS 表示 secretsmanager:GetSecretValue 应该只在调用在用于加密密钥的 CMK 上具有 kms:Decrypt 时才有效(这是有道理的)。 (见https://docs.aws.amazon.com/secretsmanager/latest/apireference/API_GetSecretValue.html

  • 我确认我的对称 KMS CMK 确实是用于加密密钥的 CMK。

  • 我的同事没有以 root 帐户登录 AWS。他以自己的帐户登录。他碰巧拥有大量权限,因为他是管理员,但我认为没有理由允许他使用我的 CMK。

  • 如果您想知道为什么我的同事为关键管理员设置 KMS 操作,那是因为他是我们的系统管理员

  • 我的 KMS CMK 上的策略是由您在创建 CMK 时在 AWS 控制台中完成的漂亮向导自动生成的。

  • 注意:注意不要将 kms:Get* 操作与 secretsmanager:Get* 操作混淆。

  • 这是我的 KMS CMK 的政策:

{
    "Id": "key-consolepolicy-3","Version": "2012-10-17","Statement": [
        {
            "Sid": "Enable IAM User Permissions","Effect": "Allow","Principal": {
                "AWS": "arn:aws:iam::REDACTED:root"
            },"Action": "kms:*","Resource": "*"
        },{
            "Sid": "Allow access for Key Administrators","Principal": {
                "AWS": [
                    "arn:aws:iam::REDACTED:user/MY_COWORKER"
                ]
            },"Action": [
                "kms:Create*","kms:Describe*","kms:Enable*","kms:List*","kms:Put*","kms:Update*","kms:Revoke*","kms:disable*","kms:Get*","kms:Delete*","kms:TagResource","kms:UntagResource","kms:ScheduleKeyDeletion","kms:CancelKeyDeletion"
            ],{
            "Sid": "Allow use of the key","Principal": {
                "AWS": "arn:aws:iam::REDACTED:user/ME"
            },"Action": [
                "kms:Encrypt","kms:Decrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey"
            ],{
            "Sid": "Allow attachment of persistent resources","Action": [
                "kms:CreateGrant","kms:ListGrants","kms:RevokeGrant"
            ],"Resource": "*","Condition": {
                "Bool": {
                    "kms:GrantIsForAWSResource": "true"
                }
            }
        }
    ]
}

解决方法

非常感谢@JohnRotenstein 为我指明了正确的方向,并在上面回答了我的问题!

解决方案背景 1

正如约翰所问的那样,当我在上面说我的同事在我们的账户上“是管理员”时,我的意思是他的 IAM 用户账户具有 AWS 托管策略 Administrator Access,可以“完全访问”(据我所知)AWS 中的所有内容或几乎所有内容(包括 KMS !!)。

解决方案背景 2

确实,在我上面的问题中,我的密钥策略(这是默认的密钥策略)包含以下声明:

{
    "Sid": "Enable IAM User Permissions","Effect": "Allow","Principal": {
        "AWS": "arn:aws:iam::REDACTED:root"
    },"Action": "kms:*","Resource": "*"
},

根据 @JohnRotenstein 的评论和 these AWS docs,此政策声明允许 IAM 政策访问和使用此密钥 - 如果这些政策指定了正确的权限。

因此(据我所知),这将允许相当多的人(任何可以在我公司账户上编辑 IAM 策略的人)能够给自己一个策略,允许他们对我的账户做任何他们想做的事情KMS钥匙! (这不安全!)

我需要解决这个问题。 (下面的解决方案!)

解决方案背景 3

在“默认 KMS 密钥策略”(我在上面的问题中发布)中,您会看到密钥管理员可以kms:Put*。允许他们kms:PutKeyPolicy,这将允许他们更改策略以给自己(或任何人)kms:Decrypt,这将允许他们解密我的 Secrets Manager 秘密并获得秘密价值!

我也需要压制这个......

解决方案

关键政策如下:

  • 确保我的 Lambda 函数可以(通过我提供给执行 Lambda 函数的 IAM 角色的策略声明)使用 IAM 策略来使用此密钥,并且他们可以kms:Decrypt

  • 只允许关键用户(我)进行加密和解密操作(当然,Lambda 函数除外;见上文)

  • 虽然密钥管理员不能使用我的密钥来加密或解密事物(或 kms:PutKeyPolicy),但他们可以执行所有管理任务,例如删除 KMS 密钥或其授权。

{
  "Id": "mount-houlis-secure-kms-key-policy","Version": "2012-10-17","Statement": [
    {
      "Sid": "Allow use of the key","Principal": {
        "AWS": THE_ARN_OF_THE_IAM_USER_WHO_OWNS_THE_SECRET____WHICH_IS_ME
      },"Action": [
        "kms:Encrypt","kms:Decrypt","kms:ReEncrypt*","kms:GenerateDataKey*","kms:DescribeKey","kms:GetKeyPolicy","kms:PutKeyPolicy"
      ],"Resource": "*"
    },{
      "Sid": "Admins","Principal": {
        "AWS": [
          ARNS_OF_VARIOUS,KEY_ADMINISTRATORS,AND_ME
        ]
      },"Action": [
        "kms:CancelKeyDeletion","kms:CreateAlias","kms:DeleteAlias","kms:DisableKey","kms:DisableKeyRotation","kms:EnableKey","kms:EnableKeyRotation","kms:GetKeyRotationStatus","kms:ListGrants","kms:ListKeyPolicies","kms:ListResourceTags","kms:ListRetirableGrants","kms:RetireGrant","kms:RevokeGrant","kms:ScheduleKeyDeletion","kms:TagResource","kms:UntagResource","kms:UpdateAlias","kms:UpdateKeyDescription"
      ],{
      "Sid": "Allow Lambda function to do Action secretsmanager:GetSecretValue","Principal": {
        "AWS": ARN_OF_THE_ROLE_THAT_YOUR_LAMBDA_FUNCTION_EXECUTES_AS____SHOULD_BE_arn:aws:iam::ACCOUNT_NUMBER:role/your-lambda-function-role-name
      },"Action": "kms:Decrypt","Resource": "*"
    }
  ]
}