For AI agents: A markdown version of this page is available at https://docs.datadoghq.com/security/code_security/iac_security/iac_rules/terraform-aws-role-with-privilege-escalation-by-actions-iam-updateassumerolepolicy-and-sts-assumerole.md. A documentation index is available at /llms.txt.

Role with privilege escalation by actions 'iam:UpdateAssumeRolePolicy' and 'sts:AssumeRole'

This product is not supported for your selected Datadog site. ().

Metadata

Id: terraform-aws-role-with-privilege-escalation-by-actions-iam-updateassumerolepolicy-and-sts-assumerole

Provider: AWS

Platform: Terraform

Severity: Medium

Category: Access Control

Learn More

Description

Granting an IAM role permissions for both iam:UpdateAssumeRolePolicy and sts:AssumeRole actions with the Resource attribute set to "*" creates a severe privilege escalation risk. This misconfiguration allows a user or role to modify the trust policies of any role and subsequently assume any role in the AWS account, potentially gaining administrative privileges. If left unaddressed, malicious actors could exploit these permissions to take over sensitive roles and perform unauthorized actions across all AWS resources.

Compliant Code Examples

# Has iam:UpdateAssumeRolePolicy but no sts:AssumeRole grant: only one of the
# two required permissions is present.
resource "aws_iam_role" "cosmic2" {
  name = "cosmic2"
}

resource "aws_iam_role_policy" "inline_policy_only" {
  name = "inline_policy_only"
  role = aws_iam_role.cosmic2.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "iam:UpdateAssumeRolePolicy",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}
# Has sts:AssumeRole via an attached managed policy but no
# iam:UpdateAssumeRolePolicy grant: only one of the two required permissions
# is present.
resource "aws_iam_role" "cosmic3" {
  name = "cosmic3"
}

resource "aws_iam_policy_attachment" "test-attach" {
  name       = "test-attachment"
  roles      = [aws_iam_role.cosmic3.name]
  policy_arn = aws_iam_policy.assume_role_policy.arn
}

resource "aws_iam_policy" "assume_role_policy" {
  name        = "assume-role-policy"
  description = "A test policy"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "sts:AssumeRole",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

Non-Compliant Code Examples

resource "aws_iam_role" "cosmic" {
  name = "cosmic"
}

resource "aws_iam_role_policy" "test_inline_policy" {
  name = "test_inline_policy"
  role = aws_iam_role.cosmic.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "iam:UpdateAssumeRolePolicy",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}


resource "aws_iam_policy_attachment" "test-attach" {
  name       = "test-attachment"
  roles      = [aws_iam_role.cosmic.name]
  policy_arn = aws_iam_policy.policy.arn
}


resource "aws_iam_policy" "policy" {
  name        = "test-policy"
  description = "A test policy"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "sts:AssumeRole",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}
resource "aws_iam_role" "nebula" {
  name = "nebula"
}

resource "aws_iam_role_policy" "update_assume_role_policy" {
  name = "update_assume_role_policy"
  role = aws_iam_role.nebula.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "iam:UpdateAssumeRolePolicy",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}

resource "aws_iam_role_policy" "assume_role_policy" {
  name = "assume_role_policy"
  role = aws_iam_role.nebula.name

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = [
          "sts:AssumeRole",
        ]
        Effect   = "Allow"
        Resource = "*"
      },
    ]
  })
}