Skip to main content

Insecure service configuration - IAM

Need

Secure configuration of IAM services

Context

  • Usage of Terraform for Infrastructure as Code (IaC)
  • Usage of terraform-provider-aws for managing AWS resources with Terraform

Description

Non compliant code

provider "aws" {
region = "us-west-2"
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
}

resource "aws_iam_user" "lb" {
name = "loadbalancer"
path = "/system/"
}

resource "aws_iam_access_key" "lb" {
user = aws_iam_user.lb.name
pgp_key = "keybase:username"
}

output "secret" {
value = aws_iam_access_key.lb.encrypted_secret
}

The above Terraform configuration code is vulnerable because it exposes sensitive information in plain text. Specifically, the access_key and secret_key for the AWS provider are hard-coded into the Terraform configuration file. These keys are extremely sensitive as they can provide full access to the AWS account.

Furthermore, an IAM user is created with a hardcoded path and name. The IAM access key is also created and associated with the IAM user. The encrypted secret key is then outputted, which could potentially be logged or stored insecurely.

This configuration is not compliant with security standards such as ISO 27017 and NIST SP 800-144, as sensitive information should not be stored in plain text or uploaded to the cloud. This could lead to data leakage and unauthorized access to the AWS account.

Steps

  • Remove the access_key and secret_key from the provider block
  • Use environment variables to store the access key and secret key
  • Retrieve the access key and secret key from the environment variables in the code
  • Ensure that the environment variables are properly protected and not exposed in the code repository
  • Consider using a secret management service to securely store and retrieve the access key and secret key

Compliant code

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

resource "aws_iam_user" "lb" {
name = "loadbalancer"
path = "/system/"
}

resource "aws_iam_access_key" "lb" {
user = aws_iam_user.lb.name
pgp_key = "keybase:username"
}

output "secret" {
value = aws_iam_access_key.lb.encrypted_secret
}

The updated code removes the access_key and secret_key from the AWS provider block. This is a critical change as hardcoding sensitive information like AWS access keys and secret keys in the code can lead to serious security vulnerabilities such as unauthorized access or data leakage.

Instead of hardcoding, these keys should be stored in environment variables. The AWS provider block will automatically use the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables if they are set.

To set these environment variables, you can use the following commands in your shell:

export AWS_ACCESS_KEY_ID="youraccesskey"
export AWS_SECRET_ACCESS_KEY="yoursecretkey"

Remember to replace "youraccesskey" and "yoursecretkey" with your actual AWS access key and secret key.

It's important to note that these environment variables should be properly protected and not exposed in the code repository. You should never commit your AWS access keys and secret keys to your code repository.

For an additional layer of security, consider using a secret management service like AWS Secrets Manager or HashiCorp Vault to securely store and retrieve your AWS access keys and secret keys. These services provide a centralized location to manage secrets and protect sensitive data using encryption.

References