Open menu
-->

CloudFormation Stack with IAM Role

Cloud Conformity allows you to automate the auditing process of this resolution page. Register for a 14 day evaluation and check your compliance level for free!

Start a Free Trial Product features
Security

Risk level: Medium (should be achieved)

Ensure that the IAM service role associated with your Amazon CloudFormation stack adhere to the principle of least privilege in order avoid unwanted privilege escalation, as users with privileges within the AWS CloudFormation scope implicitly inherit the stack role's permissions. When an IAM service role is associated with a stack, AWS CloudFormation service uses this role for all operations that are performed on that stack. Other users that have permissions to perform operations on the stack will be able to utilize this role, even if they don't have permission to pass it. If the IAM role includes permissions that other users shouldn't have, you can unintentionally escalate their permissions, therefore you need to make sure that the role adhere to the principle of least privilege by giving it the minimal set of actions required to perform its tasks.

Providing the right permissions for the IAM service role associated with your Amazon CloudFormation stack will significantly reduce the risk of unauthorized access to the AWS resources within the stack.

Audit

To determine if your AWS CloudFormation stacks have IAM service roles that grant least privilege, perform the following:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to CloudFormation dashboard at https://console.aws.amazon.com/cloudformation/.

03 Select the CloudFormation stack that you want to examine.

04 Select Overview tab from the dashboard bottom panel to view the stack configuration details.

05 Check the IAM role attribute value. If the configuration attribute does not have any value, the selected CloudFormation stack is not associated with an IAM service role, therefore the audit process stops here. If the attribute value is set to an IAM role name/ARN:

IAM service role

the selected stack is currently associated with an IAM service role. Copy the name of the IAM service role, e.g.

IAM service role

06 Navigate to IAM dashboard at https://console.aws.amazon.com/iam/.

07 In the left navigation panel, choose Roles.

08 Paste the name of the IAM service role copied at step no. 5 into the Search box and press Enter.

09 Click on the name (link) of the IAM role returned as result to access the resource details.

10 On the Summary page, select the Permissions tab and analyze the IAM policies attached to the selected IAM role. If the selected role is overly permissive policies (e.g.

Overlay Permissive Policies

), the IAM service role associated with your CloudFormation stack does not follow the principle of least privilege and this can lead to unwanted privilege escalation.

11 Repeat steps no. 3 – 10 to check other AWS CloudFormation stacks available in the current region for IAM service roles.

12 Change the AWS region from the navigation bar and repeat the audit process for other regions.

Using AWS CLI

01 Run list-stacks command (OSX/Linux/UNIX) to list the names of all CloudFormation stacks available in the selected AWS region:

aws cloudformation list-stacks
  --region us-east-1
  --output table
  --query 'StackSummaries[*].StackName'

02 The command output should return a table with the requested stack names:

---------------------
|    ListStacks     |
+-------------------+
| cc-web-app-stack  |
| cc-prod-env-stack |
+-------------------+

03 Run describe-stacks command (OSX/Linux/UNIX) using custom query filters to describe the ARN of the IAM service role (if any) associated with the selected AWS CloudFormation stack:

aws cloudformation describe-stacks
  --region us-east-1
  --stack-name cc-web-app-stack
  --query 'Stacks[*].RoleARN'

04 The command output should return the requested Amazon Resource Name (ARN):

[
    "arn:aws:iam::123456789012:role/cfn-stack-admin-role"
]

05 To analyze the associated IAM role permissions, based on the policy type used by the role, perform one of the following set of commands:

  1. For managed IAM policies:
    • Run list-attached-role-policies command (OSX/Linux/UNIX) using the name of the IAM service role as identifier (extracted from the resource ARN) to list the managed policies attached to the selected IAM role:
      aws iam list-attached-role-policies
          --role-name cfn-stack-admin-role
      
    • The command output should return the IAM policies metadata:
      {
          "AttachedPolicies": [
              {
                 "PolicyName": "AdministratorAccess",
                 "PolicyArn": "arn:aws:iam::aws:policy/AdministratorAccess"
              }
          ]
      }
      
    • Run get-policy command (OSX/Linux/UNIX) using the name of the ARN of the managed policy returned at the previous step as identifier to list the policy configuration metadata:
      aws iam get-policy
          --policy-arn arn:aws:iam::aws:policy/AdministratorAccess
      
    • The command output should return the requested metadata:
      {
          "Policy": {
              "PolicyName": "AdministratorAccess",
              "Description": "Provides full access to AWS services and resources.",
              "CreateDate": "2015-02-06T18:39:46Z",
              "AttachmentCount": 2,
              "IsAttachable": true,
              "PolicyId": "AAAABBBBCCCCDDDDEEEE",
              "DefaultVersionId": "v1",
              "Path": "/",
              "Arn": "arn:aws:iam::aws:policy/AdministratorAccess",
              "UpdateDate": "2015-02-06T18:39:46Z"
          }
      }
      
  2. For inline IAM policies:
    • Run list-role-policies command (OSX/Linux/UNIX) using the name of the service role as identifier (extracted from the IAM resource ARN) to list the inline policies defined to the selected IAM role:
      aws iam list-role-policies
          --role-name cfn-stack-admin-role
      
    • The command output should return the inline IAM policies metadata:
      {
          "PolicyNames": [
              "cc-cfn-policy"
          ]
      }
      
    • Run get-role-policy command (OSX/Linux/UNIX) using the name of the inline policy returned at the previous step as identifier to list the policy configuration metadata:
      aws iam get-role-policy
          --role-name cfn-stack-admin-role
          --policy-name cc-cfn-policy
      
    • The command output should return the requested policy metadata (including the policy document):
      {
          "RoleName": "cfn-stack-admin-role",
          "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                  {
                      "Action": "cloudformation:*",
                      "Resource": "*",
                      "Effect": "Allow",
                      "Sid": "VisualEditor0"
                  }
              ]
          },
          "PolicyName": "cc-cfn-policy"
      }
      

06 Analyze the permission (IAM policies) set for the selected IAM role, describe at step no 5 (a. and/or b.). If the selected role has overly permissive policies (e.g. "AdministratorAccess" managed policy), the IAM service role associated with your CloudFormation stack does not follow the principle of least privilege and this can lead to unwanted privilege escalation.

07 Repeat steps no. 3 – 5 to check other AWS CloudFormation stacks available in the current region for IAM service roles.

08 Perform steps no. 1 – 7 to repeat the entire audit process for the other AWS regions.

Remediation / Resolution

To update the permissions of the IAM service roles associated with CloudFormation stacks to adhere to the principle of least privilege, perform the following actions:

Using AWS Console

01 Navigate to IAM dashboard at https://console.aws.amazon.com/iam/.

02 In the left navigation panel, choose Roles.

03 Click Create role button from the dashboard top menu to create a new IAM role that will replace the existing service role within your CloudFormation stack configuration. If you don't create a new IAM service role, AWS CloudFormation uses the role that was previously associated with the stack, during the update process.

04 On Trust panel, select AWS service category and choose CloudFormation from Choose the service that will use this role list. Click Next: Permissions to continue.

05 On Permissions panel, perform one of the following actions:

  1. To attach well-defined managed policies (e.g. "AmazonEC2FullAccess"), select one or more policies from the list, then click Next: Review button to continue the setup process.
  2. To attach custom (inline) policies, click Create policy button and run the setup wizard to create a new inline IAM policy, based on your requirements. When you create a new policy, start with a minimum set of permissions and grant additional permissions as necessary. Once the inline IAM policy is created, return to the IAM role Permissions panel, click Refresh and select the newly created incline IAM policy. Once the custom policy is selected, click Next: Review button to continue the process.

06 On Review panel, provide a unique name and a description for your new IAM service role, then click Create role to finish the setup process and create the IAM role.

07 Navigate to CloudFormation dashboard at https://console.aws.amazon.com/cloudformation/.

08 Select the CloudFormation stack that you want to update.

09 Click Actions button from the dashboard top menu and select Update stack option.

10 On the Select Template panel, choose Use current template and click Next.

11 On the Specify Details panel, leave the configuration parameters unchanged and click Next.

12 On the Options panel, within Permissions section, select the newly created IAM service role from the IAM Role dropdown list to associate the new role with the selected stack. Leave the rest of the settings unchanged, then click Next.

13 On the Review panel, review the stack details and click Update to update the selected CloudFormation stack. The resource status should change to UPDATE_IN_PROGRESS and once the process is finished, to UPDATE_COMPLETE.

14 Repeat steps no. 1 – 13 to update the permissions of the IAM service roles associated with other CloudFormation stacks created in the current region.

15 Change the AWS region from the navigation bar and repeat the entire process for other regions.

Using AWS CLI

01 Now create the necessary trust relationship (Trusted Entities) policy for the IAM service role. To create the trust relationship policy for the new role, paste the following information into a new policy document named cc-service-role-trust-policy.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

02 Run create-role command (OSX/Linux/UNIX) to create the AWS IAM service role using the trust relationship policy defined at the previous step:

aws iam create-role
    --role-name cc-iam-service-role
    --assume-role-policy-document file://cc-service-role-trust-policy.json

03 The command output should return the new IAM role metadata, e.g:

{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Principal": {
                        "Service": "cloudformation.amazonaws.com"
                    },
                    "Effect": "Allow",
                    "Sid": ""
                }
            ]
        },
        "RoleId": "AAAABBBBCCCCDDDDEEEE",
        "CreateDate": "2018-02-08T16:42:20.252Z",
        "RoleName": "cc-iam-service-role",
        "Path": "/",
        "Arn": "arn:aws:iam::123456789012:role/cc-iam-service-role"
    }
}

04 To define the IAM role permissions, based on the policy type used by the role, perform one of the following set of commands:

  1. To attach managed IAM policies:
    • Run attach-role-policy command (OSX/Linux/UNIX) to attach the specified IAM managed policy to the newly created service role (the command does not produce an output):
      aws iam attach-role-policy
          --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
          --role-name cc-iam-service-role
      
  2. For define and attach inline IAM policies:
    • To define the custom (inline) policy for the service role, paste the following data into a new JSON-based policy document named cc-service-role-inline-access-policy.json. The following example, provides full access to Amazon EC2 resources:
      {
          "Version": "2012-10-17",
          "Statement": [
              {
                  "Action": "ec2:*",
                  "Effect": "Allow",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "elasticloadbalancing:*",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "cloudwatch:*",
                  "Resource": "*"
              },
              {
                  "Effect": "Allow",
                  "Action": "autoscaling:*",
                  "Resource": "*"
              }
          ]
      }
      
    • Run put-role-policy command (OSX/Linux/UNIX) to attach the inline policy defined at the previous step to the new IAM service role (the command does not produce an output):
      aws iam put-role-policy
          --role-name cc-iam-service-role
          --policy-name iam-service-role-policy
          --policy-document file://cc-service-role-inline-access-policy.json
      

05 Run update-stack command (OSX/Linux/UNIX) to update the necessary CloudFormation stack and replace the associated IAM service role with the new AWS IAM role created at step no. 3, IAM role that grants least privilege:

aws cloudformation update-stack
    --region us-east-1
    --stack-name cc-web-app-stack
    --use-previous-template
    --parameters ParameterKey=KeyName,UsePreviousValue=true ParameterKey=InstanceType,UsePreviousValue=true ParameterKey=SSHLocation,UsePreviousValue=true ParameterKey=DBName,UsePreviousValue=true ParameterKey=DBUser,UsePreviousValue=true ParameterKey=DBPassword,UsePreviousValue=true ParameterKey=DBRootPassword,UsePreviousValue=true
    --role-arn arn:aws:iam::123456789012:role/cc-iam-service-role

06 The command output should return the ID of the updated AWS CloudFormation stack:

{
    "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cc-web-app-stack/aaaabbbb-cccc-dddd-eeee=aaaabbbbcccc"
}

07 Repeat steps no. 1 – 6 to update the permissions of the IAM service roles associated with other CloudFormation stacks created in the current region.

08 Change the AWS region by updating the --region command parameter value and repeat steps no. 1 - 8 to perform the entire process for other regions.

References

Publication date Feb 9, 2018