Non-encrypted confidential information
Need
Enforcement of encryption at rest and secure storage of confidential information and credentials across AWS resources provisioned via CloudFormation
Context
• Usage of AWS CloudFormation for Infrastructure as Code (IaC)
• Ensuring data security in Amazon S3 buckets
• Usage of AWS SDK for interacting with Amazon Web Services
• Usage of AWS resources such as EFS, EBS, Redshift, and KMS for data storage and encryption
Description
1. Non compliant code
Resources:
InsecureS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-bucket
AccessControl: Private
Tags:
- Key: Name...**S3 bucket without Server-Side Encryption.** The `AccessControl` is set to `Private`, restricting public access, but there is no `BucketEncryption` property, so Server-Side Encryption (SSE) is not enabled and data at rest remains unencrypted. **RDS database with plaintext credentials and no encryption.** The `MasterUsername`/`MasterUserPassword` are written directly in the template as plain text, the instance is `PubliclyAccessible: true`, and `StorageEncrypted` is `false`, so both the credentials and the data at rest are exposed. **EFS file system without a Customer Managed Key.** No encryption configuration is specified, so EFS falls back to the default AWS-managed key, giving the customer no control over the key's lifecycle or access policies. **EBS volume without encryption.** The `Encrypted` property is omitted (or `false`), so data stored on the volume is not protected at rest. **Redshift cluster without encryption.** The `Encrypted` property is omitted from the `AWS::Redshift::Cluster` resource, so data in the cluster is not encrypted at rest, in addition to the master credentials being hard-coded in plain text.
2. Steps
• Modify the CloudFormation template to include the `BucketEncryption` property for S3 buckets, specifying `SSEAlgorithm` as `AES256` or `aws:kms`.
• Disable public access to databases (set `PubliclyAccessible` to false) and enable storage encryption (set `StorageEncrypted` to true) for RDS instances.
• Replace hard-coded database credentials with values resolved from AWS Secrets Manager (or an equivalent secrets store).
• Create and reference a Customer Managed Key (`AWS::KMS::Key`) for EFS, EBS, and Redshift resources instead of relying on default encryption or leaving it disabled.
• Set the `Encrypted` property to `true` on `AWS::EFS::FileSystem`, `AWS::EC2::Volume`, and `AWS::Redshift::Cluster` resources.
• Deploy the updated CloudFormation stack and verify, via the AWS Console or CLI, that all affected resources are encrypted and credentials are no longer stored in plain text.
• Implement IAM policies to restrict access to encryption keys and to the underlying resources.
3. Secure code example
Resources:
SecureS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-bucket
AccessControl: Private
BucketEncryption:
ServerSideEncryptionConfiguration:...**S3 bucket.** The `BucketEncryption` property is added with a `ServerSideEncryptionConfiguration` that applies `AES256` encryption by default, so all objects stored in the bucket are encrypted at rest. **RDS database.** `PubliclyAccessible` is set to `false`, `StorageEncrypted` is set to `true` (with a KMS key), and the credentials are no longer hard-coded — they are resolved at deploy time from an `AWS::SecretsManager::Secret` resource via the `{{resolve:secretsmanager:...}}` dynamic reference. **EFS file system.** A Customer Managed Key (`AWS::KMS::Key`) is created and referenced via `KmsKeyId` on the `AWS::EFS::FileSystem` resource, with `Encrypted: true`, giving the customer full control over the encryption key's lifecycle and access policy. **EBS volume.** The `Encrypted` property is set to `true`, ensuring the volume's data is protected at rest using the default (or a custom) AWS managed key. **Redshift cluster.** A dedicated `AWS::KMS::Key` is created for the cluster and referenced via `KmsKeyId`, with `Encrypted` set to `true` on the `AWS::Redshift::Cluster` resource, so data in the cluster is encrypted and only accessible with the appropriate KMS permissions.
References
• 020. Non-encrypted confidential information