Skip to main content

Insecure encryption algorithm - Default encryption

Need

Implementation of customer-controlled keys for encryption

Context

  • Usage of Terraform for Infrastructure as Code (IaC)
  • Usage of aws_s3_bucket for interacting with Amazon S3 buckets

Description

Non compliant code

resource "aws_s3_bucket" "bucket" {
bucket = "my-bucket"
acl = "private"

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = "alias/aws/s3"
sse_algorithm = "aws:kms"
}
}
}
}

In this Terraform code, an S3 bucket is being created with server-side encryption enabled. However, the encryption is configured to use the default AWS KMS key (alias/aws/s3). This is an insecure practice as the default keys are managed by AWS and not the customer.

The kms_master_key_id parameter is set to alias/aws/s3, which refers to the default AWS-managed KMS key for S3. The sse_algorithm parameter is set to aws:kms, indicating that AWS KMS is being used for the server-side encryption.

The problem with this code is that it does not provide the full benefits of the AWS KMS service. Specifically, it does not allow the customer to control and manage their own encryption keys. This can limit the customer's ability to comply with certain security and compliance requirements.

Furthermore, if the default AWS-managed key is compromised, all data encrypted with that key could be at risk. By contrast, if a customer-managed key is compromised, only the data encrypted with that specific key would be at risk.

Steps

  • Create a Customer Managed Key (CMK) in AWS Key Management Service (KMS).
  • Replace the 'kms_master_key_id' value with the ARN of the CMK created in step 1.
  • Update the 'sse_algorithm' value to 'aws:kms'.
  • Save and apply the changes to the code.

Compliant code

resource "aws_kms_key" "my_key" {
description = "My KMS key for S3 bucket encryption"
deletion_window_in_days = 7
}

resource "aws_s3_bucket" "bucket" {
bucket = "my-bucket"
acl = "private"

server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
kms_master_key_id = aws_kms_key.my_key.arn
sse_algorithm = "aws:kms"
}
}
}
}

The above code first creates a Customer Managed Key (CMK) using the aws_kms_key resource. The description attribute is used to provide a description for the key and deletion_window_in_days attribute is used to specify the number of days to retain the key after deletion.

Then, the aws_s3_bucket resource is used to create an S3 bucket with the name "my-bucket". The acl attribute is set to "private" to ensure that the bucket is not publicly accessible.

In the server_side_encryption_configuration block, the rule block is used to apply server-side encryption by default. The kms_master_key_id attribute is set to the ARN of the CMK created earlier, and the sse_algorithm attribute is set to "aws:kms" to specify that AWS KMS should be used for encryption.

This way, instead of using the default AWS managed keys, a customer managed key is used for encryption, which provides more control and security.

References