EC2 Instance Using API Keys

  • Query id: 0b93729a-d882-4803-bdc3-ac429a21f158
  • Query name: EC2 Instance Using API Keys
  • Platform: Terraform
  • Severity: Low
  • Category: Access Control
  • URL: Github

Description

EC2 instances should use roles to be granted access to other AWS services
Documentation

Code samples

Code samples with security vulnerabilities

Postitive test num. 1 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive1" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  user_data = <<EOF
#!/bin/bash
apt-get install -y awscli
export AWS_ACCESS_KEY_ID=your_access_key_id_here
export AWS_SECRET_ACCESS_KEY=your_secret_access_key_here
EOF

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 2 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive2" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  user_data = <<EOT
#!/bin/bash
apt-get install -y awscli
cat << EOF > ~/.aws/config
[default]
aws_access_key_id = somekey
aws_secret_access_key = somesecret
EOF
EOT

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 3 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive3" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  user_data = <<EOT
#!/bin/bash
apt-get install -y awscli
cat << EOF > ~/.aws/credentials
[default]
aws_access_key_id = somekey
aws_secret_access_key = somesecret
EOF
EOT

  credit_specification {
    cpu_credits = "unlimited"
  }
}

Postitive test num. 4 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive4" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  user_data_base64 = var.init_aws_cli

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 5 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive5" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  user_data_base64 = base64encode("apt-get install -y awscli; export AWS_ACCESS_KEY_ID=your_access_key_id_here; export AWS_SECRET_ACCESS_KEY=your_secret_access_key_here")

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 6 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive6" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  user_data = <<EOT
#cloud-config
repo_update: true
repo_upgrade: all

packages:
 - awscli

runcmd:
 - [ sh, -c, "echo export AWS_ACCESS_KEY_ID=my-key-id >> ~/.bashrc" ]
 - [ sh, -c, "echo export AWS_SECRET_ACCESS_KEY=my-secret >> ~/.bashrc" ]
EOT

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 7 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive7" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  provisioner "remote-exec" {
    inline = [
      "wget -O - http://config.remote.server.com/aws-credentials > ~/.aws/credentials;"
    ]
  }

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 8 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive8" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  provisioner "file" {
    source      = "conf/aws-credentials"
    destination = "~/.aws/credentials"
  }
}
Postitive test num. 9 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_instance" "positive9" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  provisioner "remote-exec" {
    inline = [
      "echo export AWS_ACCESS_KEY_ID=my-key-id >> ~/.bashrc",
      "echo export AWS_SECRET_ACCESS_KEY=my-secret >> ~/.bashrc"
    ]
  }

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Postitive test num. 10 - tf file
module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 3.0"

  name = "single-instance"

  ami                    = "ami-ebd02392"
  instance_type          = "t2.micro"
  key_name               = "user1"
  monitoring             = true
  vpc_security_group_ids = ["sg-12345678"]
  subnet_id              = "subnet-eddcdzz4"

  user_data = <<EOF
#!/bin/bash
apt-get install -y awscli
export AWS_ACCESS_KEY_ID=your_access_key_id_here
export AWS_SECRET_ACCESS_KEY=your_secret_access_key_here
EOF


  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}
Postitive test num. 11 - tf file
module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 3.0"

  name = "single-instance"

  ami                    = "ami-ebd02392"
  instance_type          = "t2.micro"
  key_name               = "user1"
  monitoring             = true
  vpc_security_group_ids = ["sg-12345678"]
  subnet_id              = "subnet-eddcdzz4"

  user_data_base64 = var.init_aws_cli


  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}
Postitive test num. 12 - tf file
module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 3.0"

  name = "single-instance"

  ami                    = "ami-ebd02392"
  instance_type          = "t2.micro"
  key_name               = "user1"
  monitoring             = true
  vpc_security_group_ids = ["sg-12345678"]
  subnet_id              = "subnet-eddcdzz4"

  user_data_base64 = base64encode("apt-get install -y awscli; export AWS_ACCESS_KEY_ID=your_access_key_id_here; export AWS_SECRET_ACCESS_KEY=your_secret_access_key_here")


  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}

Code samples without security vulnerabilities

Negative test num. 1 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_iam_role_policy_attachment" "test_attach" {
  roles      = [aws_iam_role.test_role.name]
  policy_arn = aws_iam_policy.test_policy.arn
}

resource "aws_iam_policy" "test_policy" {
  name = "test_policy"
  description = "test policy"
  path = "/"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Action": [
              "s3:Get*",
              "s3:List*"
          ],
          "Effect": "Allow",
          "Resource": "*"
      }
  ]
}
EOF
}

resource "aws_iam_role" "test_role" {
  name = "test_role"
  path = "/"

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

resource "aws_iam_instance_profile" "test_profile" {
  name = "test_profile"
  role = aws_iam_role.role.name
}

resource "aws_instance" "negative1" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  iam_instance_profile = aws_iam_instance_profile.test_profile.name

  credit_specification {
    cpu_credits = "unlimited"
  }
}
Negative test num. 2 - tf file
module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 3.0"

  name = "single-instance"

  ami                    = "ami-ebd02392"
  instance_type          = "t2.micro"
  key_name               = "user1"
  monitoring             = true
  vpc_security_group_ids = ["sg-12345678"]
  subnet_id              = "subnet-eddcdzz4"

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }
}
Negative test num. 3 - tf file
provider "aws" {
  region = "us-east-1"
}

resource "aws_iam_role_policy_attachment" "test_attach" {
  roles      = [aws_iam_role.test_role.name]
  policy_arn = aws_iam_policy.test_policy.arn
}

resource "aws_iam_policy" "test_policy" {
  name = "test_policy"
  description = "test policy"
  path = "/"
  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
      {
          "Action": [
              "s3:Get*",
              "s3:List*"
          ],
          "Effect": "Allow",
          "Resource": "*"
      }
  ]
}
EOF
}

resource "aws_iam_role" "test_role" {
  name = "test_role"
  path = "/"

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

resource "aws_iam_instance_profile" "test_profile" {
  name = "test_profile"
  role = aws_iam_role.role.name
}

resource "aws_instance" "negative3" {
  ami           = "ami-005e54dee72cc1d00" # us-west-2
  instance_type = "t2.micro"

  tags = {
    Name = "test"
  }

  iam_instance_profile = aws_iam_instance_profile.test_profile.name

  credit_specification {
    cpu_credits = "unlimited"
  }

  user_data = <<-EOF
    #!/bin/bash
    apt-get update
  EOF
}

Negative test num. 4 - tf file
module "ec2_instance" {
  source  = "terraform-aws-modules/ec2-instance/aws"
  version = "~> 3.0"

  name = "single-instance"

  ami                    = "ami-ebd02392"
  instance_type          = "t2.micro"
  key_name               = "user1"
  monitoring             = true
  vpc_security_group_ids = ["sg-12345678"]
  subnet_id              = "subnet-eddcdzz4"

  tags = {
    Terraform   = "true"
    Environment = "dev"
  }

  user_data = <<-EOF
    #!/bin/bash
    apt-get update
  EOF
}