Skip to main content

Excessive privileges - AWS

Need

Restriction of privileges to the minimum necessary level

Context

  • Usage of Terraform for Infrastructure as Code (IaC)
  • Usage of AWS SDK for interacting with Amazon Web Services

Description

Non compliant code

provider "aws" {
region = "us-west-2"
}

resource "aws_iam_role" "iam_role" {
name = "iam_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy" "iam_role_policy" {
name = "iam_role_policy"
role = "${aws_iam_role.iam_role.id}"

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "*",
"Resource": "*",
"Effect": "Allow"
}
]
}
EOF
}

The above Terraform code creates an IAM role (aws_iam_role) and attaches a policy (aws_iam_role_policy) to it. The IAM role is allowed to assume the role from any EC2 service.

The vulnerability lies in the policy attached to the IAM role. The policy allows any action ("Action": "*") on any resource ("Resource": "*") in AWS. This means the role has excessive privileges and can perform any action on any resource in AWS.

This is a security risk as if the role's credentials are compromised, the attacker can perform any action on any resource, potentially leading to unauthorized access, data leakage, or even a complete takeover of the AWS account.

The principle of least privilege is not followed here. The principle of least privilege recommends that a user, program or system process should have the minimal privileges necessary to complete its job. Overprivileged roles or users can lead to misuse, whether intentional (malicious insiders) or accidental (misuse of permissions).

Steps

  • Review the permissions required by the application, user, or role.
  • Identify the specific actions and resources that are necessary for the application to function properly.
  • Remove the 'Allow' statement with the wildcard (*) in the 'aws_iam_role_policy' resource.
  • Replace the wildcard (*) with the specific actions and resources required by the application.
  • Ensure that the permissions assigned to the role follow the principle of least privilege.
  • Test the application to verify that it functions correctly with the updated permissions.

Compliant code

provider "aws" {
region = "us-west-2"
}

resource "aws_iam_role" "iam_role" {
name = "iam_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}

resource "aws_iam_role_policy" "iam_role_policy" {
name = "iam_role_policy"
role = "${aws_iam_role.iam_role.id}"

policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": ["ec2:Describe*", "ec2:StartInstances", "ec2:StopInstances"],
"Resource": ["arn:aws:ec2:us-west-2:123456789012:instance/*"],
"Effect": "Allow"
}
]
}
EOF
}

The original code had a vulnerability where the IAM role had excessive privileges. The IAM role policy allowed all actions ("Action": "*") on all resources ("Resource": "*"). This is a security risk as it violates the principle of least privilege, which states that a user should have only the privileges necessary to perform their job.

The fixed code reduces the permissions of the IAM role to only what is necessary. The IAM role policy now only allows specific EC2 actions ("Action": ["ec2:Describe*", "ec2:StartInstances", "ec2:StopInstances"]) on specific EC2 instances ("Resource": ["arn:aws:ec2:us-west-2:123456789012:instance/*"]).

This ensures that the IAM role cannot perform any actions or access any resources that it does not need to, reducing the potential damage if the role's credentials were to be compromised.

References