Skip to main content

Guessed weak credentials

Need

Enhancement of credential security

Context

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

Description

Non compliant code

provider "aws" {
access_key = "AKIAIOSFODNN7EXAMPLE"
secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
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"
}

This Terraform script is setting up an AWS provider and an IAM user with access keys. The access_key and secret_key are hard-coded credentials which are considered weak and insecure as they can be easily discovered and exploited.

Also, the IAM user loadbalancer is created with an access key. This key is associated with a PGP key from keybase, which may not be secure depending on how the keybase account is managed.

This script does not enforce any password policies such as minimum length, complexity requirements, or rotation policies. This makes the credentials easier to guess, increasing the risk of a successful brute force attack.

In addition, storing secrets in plain text in your Terraform files is a bad practice. These secrets will be included in every version of your code that is committed to your repository, making it very easy for an attacker who gains access to your repository to also gain access to your AWS account.

Steps

  • Generate strong and complex access key and secret key for the AWS provider.
  • Implement a password policy that enforces strong passwords for the IAM user.
  • Avoid using default or easily guessable values for access key and secret key.
  • Regularly rotate the access key and secret key to minimize the risk of compromise.
  • Consider using a secure key management system to store and manage the access key and secret key.
  • Monitor and log failed login attempts to detect and respond to brute force attacks.

Compliant code

data "aws_caller_identity" "current" {}

provider "aws" {
region = "us-west-2"
shared_credentials_file = "~/.aws/credentials"
profile = "default"
}

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

resource "aws_iam_access_key" "lb" {
user = aws_iam_user.lb.name
}

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

resource "aws_iam_account_password_policy" "strict" {
minimum_password_length = 14
require_lowercase_characters = true
require_numbers = true
require_uppercase_characters = true
require_symbols = true
allow_users_to_change_password = true
}

The updated code now uses a shared credentials file for the AWS provider, which is a more secure way to handle access keys and secret keys. The access key and secret key are no longer hardcoded in the Terraform configuration file, reducing the risk of them being compromised.

The aws_iam_user_login_profile resource is used to create a login profile for the IAM user, which allows the user to log in to the AWS Management Console.

A password policy is enforced using the aws_iam_account_password_policy resource. This policy requires a minimum password length of 14 characters and requires the use of lowercase characters, numbers, uppercase characters, and symbols. It also allows users to change their password.

This approach significantly increases the complexity of the system credentials, making it much more difficult for an attacker to guess them. It also allows for the regular rotation of access keys and secret keys, further reducing the risk of compromise.

References