logo

Non-encrypted confidential information - DynamoDB - Aws


Need

Secure encryption of confidential information in DynamoDB


Context

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

Description

Insecure Code Example

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

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

Secure Code Example

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

  • 409 - Non-encrypted confidential information - DynamoDB

  • Last updated

    2023/09/18