Skip to main content

Non-encrypted confidential information - DB

Need

Secure storage of confidential information in the database

Context

  • Usage of Terraform for Infrastructure as Code (IaC)
  • Usage of AWS SDK for interacting with Amazon Web Services

Description

Non compliant code

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

resource "aws_db_instance" "default" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "foo"
password = "foobarbaz"
parameter_group_name = "default.mysql5.7"
publicly_accessible = true
}

In the above code, the Terraform script is creating an AWS RDS instance with a publicly accessible MySQL database. The database is configured with a username and password, which are directly written in the script. However, the password is a plain text string, which is a security vulnerability as it can be easily read by anyone who has access to this script.

Moreover, the database instance is publicly accessible, which means it can be accessed from any IP address, making it susceptible to attacks from anyone on the internet.

Another point to note is that the data stored in this database is not encrypted. AWS RDS supports encryption at rest for many of its database engines, but it's not being utilized in this script.

The combination of these factors makes this code vulnerable to attacks where an attacker can gain unauthorized access to the database and any information stored within it.

Steps

  • Enable encryption at rest for the database instance
  • Use SSL/TLS to encrypt data in transit between the application and the database
  • Implement strong access controls and authentication mechanisms for the database
  • Regularly update and patch the database software to address any security vulnerabilities

Compliant code

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

resource "aws_db_instance" "default" {
allocated_storage = 20
storage_type = "gp2"
engine = "mysql"
engine_version = "5.7"
instance_class = "db.t2.micro"
name = "mydb"
username = "foo"
password = "foobarbaz"
parameter_group_name = "default.mysql5.7"
publicly_accessible = true
storage_encrypted = true
kms_key_id = "arn:aws:kms:us-west-2:123456789012:key/abcd1234-a123-456a-a12b-a123b4cd56ef"
}

resource "aws_db_option_group" "default" {
engine_name = "mysql"
major_engine_version = "5.7"
option_group_description = "Option group for enabling SSL"
option {
option_name = "MARIADB_ENABLE_SSL"
option_settings {
name = "MARIADB_ENABLE_SSL"
value = "ON"
}
}
}

The updated code includes two major changes to address the vulnerability:

  1. Encryption at Rest: The storage_encrypted attribute is set to true in the aws_db_instance resource. This ensures that the data at rest is encrypted. The kms_key_id attribute is also added to specify the AWS Key Management Service (KMS) key identifier for the encryption. Replace the placeholder ARN with your actual KMS key ARN.

  2. SSL/TLS for Data in Transit: A new aws_db_option_group resource is added. This resource is used to enable SSL for the MySQL database. The option_name is set to MARIADB_ENABLE_SSL and the value is set to ON. This ensures that the data in transit between the application and the database is encrypted.

Please note that this code does not include the implementation of strong access controls and authentication mechanisms for the database, and the regular update and patch of the database software. These are important steps that should be taken to further secure the database, but they are beyond the scope of this code snippet.

References