logo

Non-encrypted confidential information - DB - Cloudformation


Need

Secure storage of confidential information in the database


Context

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

Description

Insecure Code Example

Resources:
  InsecureDB:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: mydb
      AllocatedStorage: 20
      DBInstanceClass: db.t2.micro
      Engine: mysql
      EngineVersion: "5.7"
      MasterUsername: admin
      MasterUserPassword: my_password
      PubliclyAccessible: true
      StorageEncrypted: false

The above CloudFormation template creates 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 template as plaintext. This poses a security risk since anyone with access to the CloudFormation template can view the credentials. Additionally, the database instance is publicly accessible, meaning it can be reached from any IP address, making it susceptible to unauthorized access. Furthermore, encryption at rest is not enabled, meaning sensitive data stored in the database is unprotected. These misconfigurations increase the risk of data breaches and unauthorized access.

Steps

  1. Disable public access to the database to prevent unauthorized access.
  2. Enable encryption at rest to protect stored data.
  3. Use AWS Secrets Manager to securely store and manage database credentials.
  4. Implement IAM policies to restrict access to the database.

Secure Code Example

Resources:
  SecureDB:
    Type: AWS::RDS::DBInstance
    Properties:
      DBInstanceIdentifier: mydb
      AllocatedStorage: 20
      DBInstanceClass: db.t2.micro
      Engine: mysql
      EngineVersion: "5.7"
      MasterUsername: !Sub "{{resolve:secretsmanager:my_db_secret:SecretString:username}}"
      MasterUserPassword: !Sub "{{resolve:secretsmanager:my_db_secret:SecretString:password}}"
      PubliclyAccessible: false
      StorageEncrypted: true
      KmsKeyId: arn:aws:kms:us-west-2:123456789012:key/abcd1234-a123-456a-a12b-a123b4cd56ef

  DBSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: my_db_secret
      SecretString: !Sub |
        {
          "username": "admin",
          "password": "securepassword123"
        }

The above CloudFormation template mitigates the security risks by: 1. **Disabling Public Access**: The `PubliclyAccessible` property is set to `false` to ensure the database is only accessible within the private network. 2. **Enabling Encryption at Rest**: The `StorageEncrypted` property is set to `true` to ensure data stored in the database is encrypted. 3. **Using AWS Secrets Manager**: Instead of hardcoding credentials, Secrets Manager is used to securely store and retrieve database credentials.


References

  • 246 - Non-encrypted confidential information - DB

  • Last updated

    2025/04/03