Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EC2 Instance Using API Keys Security Query False Positive Result #5890

Closed
cxMiguelSilva opened this issue Oct 3, 2022 · 0 comments · Fixed by #5903
Closed

EC2 Instance Using API Keys Security Query False Positive Result #5890

cxMiguelSilva opened this issue Oct 3, 2022 · 0 comments · Fixed by #5903
Labels
bug Something isn't working community Community contribution hacktoberfest query New query feature

Comments

@cxMiguelSilva
Copy link
Collaborator

cxMiguelSilva commented Oct 3, 2022

Actual Behavior

EC2 Instance Using API Keys finds False positive result in line 288 as non-existent API keys were flagged.

{
	"query_name": "EC2 Instance Using API Keys",
	"query_id": "0b93729a-d882-4803-bdc3-ac429a21f158",
	"query_url": "https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance#iam_instance_profile",
	"severity": "LOW",
	"platform": "Terraform",
	"cloud_provider": "AWS",
	"category": "Access Control",
	"description": "EC2 instances should use roles to be granted access to other AWS services",
	"description_id": "ffd8ce80",
	"files": [
		{
			"file_name": "../../path/main.tf",
			"similarity_id": "f4b07a02b8eb707fd322f4d0a25a366ec6caa55f496b6ab57aebed9c3310eb30",
			"line": 288,
			"resource_type": "aws_instance",
			"resource_name": "web-app-instance",
			"issue_type": "MissingAttribute",
			"search_key": "aws_instance[web-app-instance]",
			"search_line": 0,
			"search_value": "",
			"expected_value": "aws_instance[web-app-instance] should be using iam_instance_profile to assign a role with permissions",
			"actual_value": "aws_instance[web-app-instance].user_data is being used to configure AWS API keys"
		}
	]
},

Steps to Reproduce the Problem

  1. Run KICS Scan command
    docker run -v /path/to/folder:/path checkmarx/kics:v1.6.1 scan -p /path/sample.tf

Sample to reproduce the problem:

terraform {
  backend "s3" {
    bucket = "terraform-jenkins-demo"
    key    = "terraform.tfstate"
    region = "us-east-1"
  }
}

#IAM Role
resource "aws_iam_role" "web-app-instance-role" {
  assume_role_policy = <<POLICY
{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      }
    }
  ],
  "Version": "2012-10-17"
}
POLICY

  description          = "Allows EC2 instances to call AWS services on your behalf."
  max_session_duration = "3600"
  name                 = "web-app-role"
  path                 = "/"

  tags = {
    name = "demo-instance-1"
  }
}

resource "aws_iam_role" "privileged-instance-role" {
  assume_role_policy = <<POLICY
{
  "Statement": [
    {
      "Action": "sts:AssumeRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      }
    }
  ],
  "Version": "2012-10-17"
}
POLICY

  description          = "Allows EC2 instances to call AWS services on your behalf."
  max_session_duration = "3600"
  name                 = "admin-role"
  path                 = "/"

  tags = {
    name = "demo-instance-2"
  }
}

#IAM Role policy
resource "aws_iam_policy" "web-app-instance-policy" {
  name        = "web-instance-policy"
  description = "Provides full access to Amazon EC2 via the AWS Management Console"
  policy      = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": ["ec2:*"],
            "Effect": "Allow",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": ["elasticloadbalancing:*"],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": ["cloudwatch:*"],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
              "iam:*"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": "iam:CreateServiceLinkedRole",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "iam:AWSServiceName": [
                        "autoscaling.amazonaws.com",
                        "ec2scheduled.amazonaws.com",
                        "elasticloadbalancing.amazonaws.com",
                        "spot.amazonaws.com",
                        "spotfleet.amazonaws.com",
                        "transitgateway.amazonaws.com"
                    ]
                }
            }
        }
    ]
}
POLICY
}

resource "aws_iam_policy" "privileged-instance-policy" {
  name        = "privileged-instance-policy"
  description = "Provides full access to AWS services and resources."
  policy      = <<POLICY
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
        "*"
      ],
            "Resource": "*"
        }
    ]
}
POLICY
}

#IAM Role Policy Attachment
resource "aws_iam_role_policy_attachment" "privileged-instance-attachment" {
  policy_arn = aws_iam_policy.privileged-instance-policy.arn
  role       = aws_iam_role.privileged-instance-role.name
}

resource "aws_iam_role_policy_attachment" "web-app-instance-attachment" {
  policy_arn = aws_iam_policy.web-app-instance-policy.arn
  role       = aws_iam_role.web-app-instance-role.name
}

#IAM Instance Profile
resource "aws_iam_instance_profile" "web-app-instance-profile" {
  name = "web-app-instance-profile"
  path = "/"
  role = aws_iam_role.web-app-instance-role.name
}

resource "aws_iam_instance_profile" "privileged-instance-profile" {
  name = "privileged-instance-profile"
  path = "/"
  role = aws_iam_role.privileged-instance-role.name
}

resource "aws_vpc" "demo-vpc" {
  assign_generated_ipv6_cidr_block = "false"
  cidr_block                       = "10.10.0.0/16"
  enable_classiclink               = "false"
  enable_classiclink_dns_support   = "false"
  enable_dns_hostnames             = "true"
  enable_dns_support               = "true"
  instance_tenancy                 = "default"

  tags = {
    Name = "demo-vpc"
  }
}

#internet gateway
resource "aws_internet_gateway" "demo-igw" {
  tags = {
    Name = "demo-igw"
  }

  vpc_id = aws_vpc.demo-vpc.id
}

#subnet
resource "aws_subnet" "subnet-1" {
  assign_ipv6_address_on_creation = "false"
  cidr_block                      = "10.10.10.0/24"
  map_public_ip_on_launch         = "false"

  tags = {
    Name = "public-subnet-01"
  }

  vpc_id = aws_vpc.demo-vpc.id
}

resource "aws_subnet" "subnet-2" {
  assign_ipv6_address_on_creation = "false"
  cidr_block                      = "10.10.20.0/24"
  map_public_ip_on_launch         = "false"

  tags = {
    Name = "public-subnet-02"
  }

  vpc_id = aws_vpc.demo-vpc.id
}

#route table
resource "aws_route_table" "demo-route-table" {
  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.demo-igw.id
  }

  tags = {
    Name = "acc-test-route-table"
  }

  vpc_id = aws_vpc.demo-vpc.id
}

#route table association
resource "aws_route_table_association" "subnet-1-association" {
  route_table_id = aws_route_table.demo-route-table.id
  subnet_id      = aws_subnet.subnet-1.id
}

resource "aws_route_table_association" "subnet-2-association" {
  route_table_id = aws_route_table.demo-route-table.id
  subnet_id      = aws_subnet.subnet-2.id
}

#Security Groups
resource "aws_security_group" "web-app-security-group" {
  description = "Allow SSH connection"

  egress {
    cidr_blocks      = ["0.0.0.0/0"]
    from_port        = 0
    ipv6_cidr_blocks = ["::/0"]
    protocol         = "-1"
    self             = "false"
    to_port          = 0
  }

  ingress {
    cidr_blocks = ["0.0.0.0/0"]
    from_port   = 0
    protocol    = "tcp"
    self        = "false"
    to_port     = 65535
  }

  ingress {
    cidr_blocks      = ["0.0.0.0/0"]
    from_port        = 22
    ipv6_cidr_blocks = ["::/0"]
    protocol         = "tcp"
    self             = "false"
    to_port          = 22
  }

  ingress {
    cidr_blocks      = ["0.0.0.0/0"]
    from_port        = 80
    ipv6_cidr_blocks = ["::/0"]
    protocol         = "tcp"
    self             = "false"
    to_port          = 80
  }

  ingress {
    cidr_blocks      = ["0.0.0.0/0"]
    from_port        = 8080
    ipv6_cidr_blocks = ["::/0"]
    protocol         = "tcp"
    self             = "false"
    to_port          = 8080
  }

  name   = "ssh-security-group"
  vpc_id = aws_vpc.demo-vpc.id
}

#AWS Key pair
resource "aws_key_pair" "cg-ec2-key-pair" {
  key_name   = "demo-env"
  public_key = file(var.ssh-public-key-for-ec2)
}

resource "aws_instance" "web-app-instance" {
  ami                         = "ami-00ddb0e5626798373"
  associate_public_ip_address = "true"

  subnet_id = aws_subnet.subnet-1.id

  vpc_security_group_ids = [aws_security_group.web-app-security-group.id]

  iam_instance_profile = aws_iam_instance_profile.web-app-instance-profile.name

  disable_api_termination = "false"
  ebs_optimized           = "false"

  enclave_options {
    enabled = "false"
  }

  get_password_data  = "false"
  hibernation        = "false"
  instance_type      = "t2.micro"
  ipv6_address_count = "0"
  key_name           = aws_key_pair.cg-ec2-key-pair.key_name

  metadata_options {
    http_endpoint               = "enabled"
    http_put_response_hop_limit = "1"
    http_tokens                 = "optional"
  }

  monitoring = "false"
  private_ip = "10.10.10.55"

  root_block_device {
    delete_on_termination = "true"
    encrypted             = "false"
    throughput            = "0"
    volume_size           = "8"
    volume_type           = "gp2"
  }

  source_dest_check = "true"

  tags = {
    Name = "web-app-instance"
  }

  tenancy = "default"

  provisioner "file" {
    source      = "./assets/ssrf_app/app.zip"
    destination = "/home/ubuntu/app.zip"
    connection {
      type        = "ssh"
      user        = "ubuntu"
      private_key = file(var.ssh-private-key-for-ec2)
      host        = self.public_ip
    }
  }
  user_data = <<-EOF
        #!/bin/bash
        apt-get update
        curl -sL https://deb.nodesource.com/setup_10.x | sudo -E bash -
        DEBIAN_FRONTEND=noninteractive apt-get -y install nodejs unzip
        npm install http express needle command-line-args
        cd /home/ubuntu
        unzip app.zip -d ./app
        cd app
        sudo node ssrf-demo-app.js &
        echo -e "\n* * * * * root node /home/ubuntu/app/ssrf-demo-app.js &\n* * * * * root sleep 10; node /home/ubuntu/app/ssrf-demo-app.js &\n* * * * * root sleep 20; node /home/ubuntu/app/ssrf-demo-app.js &\n* * * * * root sleep 30; node /home/ubuntu/app/ssrf-demo-app.js &\n* * * * * root sleep 40; node /home/ubuntu/app/ssrf-demo-app.js &\n* * * * * root sleep 50; node /home/ubuntu/app/ssrf-demo-app.js &\n" >> /etc/crontab
        EOF

  volume_tags = {
    Name = "web-app-instance"
  }

}

resource "aws_instance" "privileged-instance" {
  ami                         = "ami-00ddb0e5626798373"
  associate_public_ip_address = "true"

  disable_api_termination = "false"
  ebs_optimized           = "false"

  enclave_options {
    enabled = "false"
  }

  get_password_data    = "false"
  hibernation          = "false"
  iam_instance_profile = aws_iam_instance_profile.privileged-instance-profile.name
  instance_type        = "t2.micro"
  ipv6_address_count   = "0"
  key_name             = aws_key_pair.cg-ec2-key-pair.key_name

  metadata_options {
    http_endpoint               = "enabled"
    http_put_response_hop_limit = "1"
    http_tokens                 = "optional"
  }

  monitoring = "false"
  private_ip = "10.10.20.69"

  root_block_device {
    delete_on_termination = "true"
    encrypted             = "false"
    throughput            = "0"
    volume_size           = "8"
    volume_type           = "gp2"
  }

  source_dest_check = "true"
  subnet_id         = aws_subnet.subnet-2.id

  tags = {
    Name = "instance-2"
  }

  tenancy = "default"

  vpc_security_group_ids = [aws_security_group.web-app-security-group.id]

  volume_tags = {
    Name = "instance-2"
  }

}

output "public_dns" {
  description = "List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
  value       = aws_instance.web-app-instance.public_dns
}

@cxMiguelSilva cxMiguelSilva added bug Something isn't working query New query feature community Community contribution hacktoberfest labels Oct 3, 2022
patrickpichler pushed a commit to patrickpichler/kics that referenced this issue Oct 3, 2022
Fix user_data in aws_instance reporting false positive, even when API
keys are not present in string.

Closes Checkmarx#5890
rafaela-soares pushed a commit that referenced this issue Oct 4, 2022
Fix user_data in aws_instance reporting false positive, even when API
keys are not present in string.

Closes #5890

Co-authored-by: Patrick Pichler <git@patrickpichler.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working community Community contribution hacktoberfest query New query feature
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant