Skip to main content

Non-encrypted confidential information - DynamoDB

Need

Secure encryption of confidential information in DynamoDB

Context

  • Usage of Terraform for Infrastructure as Code (IaC)
  • Usage of aws-sdk for interacting with Amazon Web Services (AWS) services

Description

Non compliant code

resource "aws_dynamodb_table" "basic-dynamodb-table" {
name = "GameScores"
billing_mode = "PROVISIONED"
read_capacity = 20
write_capacity = 20
hash_key = "UserId"
range_key = "GameTitle"

attribute {
name = "UserId"
type = "N"
}

attribute {
name = "GameTitle"
type = "S"
}
}

The vulnerable code above demonstrates a DynamoDB table being created without any encryption specified. The aws_dynamodb_table resource block does not include the server_side_encryption argument which is used to enable server-side encryption using an AWS managed KMS key or a Customer managed KMS key (CMK).

Because encryption is not specified, the DynamoDB table will use the default AWS managed KMS key for server-side encryption. This default key does not provide the same level of control and security as a CMK.

For example, with a CMK, you can create, rotate, disable, and define access controls, and you can audit the encryption keys used to protect your data. Also, AWS does not have access to your CMKs, which means the data is securely protected.

Therefore, the code is vulnerable as it does not use a CMK for encryption, potentially leading to unauthorized access or data breaches.

Steps

  • Create a Customer Managed Key (CMK) in AWS Key Management Service (KMS)
  • Enable encryption for the DynamoDB table
  • Specify the CMK to be used for encryption in the DynamoDB table configuration

Compliant code

resource "aws_kms_key" "dynamodb" {
description = "KMS key for DynamoDB"
policy = <<POLICY
{
"Version": "2012-10-17",
"Id": "key-consolepolicy-3",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::${var.account_id}:root"},
"Action": "kms:*",
"Resource": "*"
}
]
}

resource "aws_dynamodb_table" "basic-dynamodb-table" {
name = "GameScores"
billing_mode = "PROVISIONED"
read_capacity = 20
write_capacity = 20
hash_key = "UserId"
range_key = "GameTitle"
kms_key_arn = aws_kms_key.dynamodb.arn

attribute {
name = "UserId"
type = "N"
}

attribute {
name = "GameTitle"
type = "S"
}
}

The above code first creates a Customer Managed Key (CMK) using the aws_kms_key resource. This key is then used to encrypt the DynamoDB table by specifying the kms_key_arn attribute in the aws_dynamodb_table resource.

The aws_kms_key resource creates a new KMS key with a policy that allows all KMS actions for the root user of the AWS account. The ARN of the created key is then used in the aws_dynamodb_table resource to enable server-side encryption using the created CMK.

This ensures that all data stored in the DynamoDB table is encrypted using the specified CMK, thereby fixing the vulnerability of non-encrypted confidential information.

References