logo

Non-encrypted confidential information - DB - Aws


Need

Secure storage of confidential information in the database


Context

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

Description

Insecure Code Example

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

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

Secure Code Example

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

  • 246 - Non-encrypted confidential information - DB

  • Last updated

    2023/09/18