ElastiCache With Disabled at Rest Encryption

  • Query id: e4ee3903-9225-4b6a-bdfb-e62dbadef821
  • Query name: ElastiCache With Disabled at Rest Encryption
  • Platform: CloudFormation
  • Severity: High
  • Category: Encryption
  • URL: Github

Description

Ensure AWS ElastiCache Redis clusters have encryption for data at rest enabled
Documentation

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - yaml file
AWSTemplateFormatVersion: '2010-09-09'
Description: 'State: ElastiCache redis, a cloudonaut.io template'
Resources:
  ReplicationGroup:
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
    Type: AWS::ElastiCache::ReplicationGroup
    Properties:
      ReplicationGroupDescription: !Ref 'AWS::StackName'
      AtRestEncryptionEnabled: false
      AuthToken: !If [HasAuthToken, !Ref AuthToken, !Ref 'AWS::NoValue']
      AutomaticFailoverEnabled: !If [HasAutomaticFailoverEnabled, true, false]
      CacheNodeType: !Ref CacheNodeType
      CacheParameterGroupName: !Ref CacheParameterGroup
      CacheSubnetGroupName: !Ref CacheSubnetGroupName
      Engine: redis
      EngineVersion: !Ref EngineVersion
      KmsKeyId: !If [HasKmsKey, {'Fn::ImportValue': !Sub '${ParentKmsKeyStack}-KeyId'}, !Ref 'AWS::NoValue']
      NotificationTopicArn: !If [HasAlertTopic, {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}, !Ref 'AWS::NoValue']
      NumNodeGroups: !Ref NumShards
      ReplicasPerNodeGroup: !Ref NumReplicas
      PreferredMaintenanceWindow: 'sat:07:00-sat:08:00'
      SecurityGroupIds:
      - !Ref SecurityGroup
      SnapshotName: !If [HasSnapshotName, !Ref SnapshotName, !Ref 'AWS::NoValue']
      SnapshotRetentionLimit: !Ref SnapshotRetentionLimit
      SnapshotWindow: '00:00-03:00'
      TransitEncryptionEnabled: !Ref TransitEncryption
Positive test num. 2 - yaml file
AWSTemplateFormatVersion: '2010-09-09'
Description: 'State: ElastiCache redis, a cloudonaut.io template'
Resources:
  MyReplicationGroup:
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
    Type: AWS::ElastiCache::ReplicationGroup
    Properties:
      ReplicationGroupDescription: !Ref 'AWS::StackName'
      AuthToken: !If [HasAuthToken, !Ref AuthToken, !Ref 'AWS::NoValue']
      AutomaticFailoverEnabled: !If [HasAutomaticFailoverEnabled, true, false]
      CacheNodeType: !Ref CacheNodeType
      CacheParameterGroupName: !Ref CacheParameterGroup
      CacheSubnetGroupName: !Ref CacheSubnetGroupName
      Engine: redis
      EngineVersion: !Ref EngineVersion
      KmsKeyId: !If [HasKmsKey, {'Fn::ImportValue': !Sub '${ParentKmsKeyStack}-KeyId'}, !Ref 'AWS::NoValue']
      NotificationTopicArn: !If [HasAlertTopic, {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}, !Ref 'AWS::NoValue']
      NumNodeGroups: !Ref NumShards
      ReplicasPerNodeGroup: !Ref NumReplicas
      PreferredMaintenanceWindow: 'sat:07:00-sat:08:00'
      SecurityGroupIds:
      - !Ref SecurityGroup
      SnapshotName: !If [HasSnapshotName, !Ref SnapshotName, !Ref 'AWS::NoValue']
      SnapshotRetentionLimit: !Ref SnapshotRetentionLimit
      SnapshotWindow: '00:00-03:00'
      TransitEncryptionEnabled: !Ref TransitEncryption
    UpdatePolicy:
      UseOnlineResharding: true
Positive test num. 3 - json file
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "State: ElastiCache redis, a cloudonaut.io template",
  "Resources": {
    "ReplicationGroup": {
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot",
      "Type": "AWS::ElastiCache::ReplicationGroup",
      "Properties": {
        "AutomaticFailoverEnabled": [
          "HasAutomaticFailoverEnabled",
          true,
          false
        ],
        "CacheNodeType": "CacheNodeType",
        "CacheParameterGroupName": "CacheParameterGroup",
        "CacheSubnetGroupName": "CacheSubnetGroupName",
        "EngineVersion": "EngineVersion",
        "AtRestEncryptionEnabled": false,
        "KmsKeyId": [
          "HasKmsKey",
          {
            "Fn::ImportValue": "${ParentKmsKeyStack}-KeyId"
          },
          "AWS::NoValue"
        ],
        "NotificationTopicArn": [
          "HasAlertTopic",
          {
            "Fn::ImportValue": "${ParentAlertStack}-TopicARN"
          },
          "AWS::NoValue"
        ],
        "SnapshotRetentionLimit": "SnapshotRetentionLimit",
        "TransitEncryptionEnabled": "TransitEncryption",
        "ReplicationGroupDescription": "AWS::StackName",
        "Engine": "redis",
        "ReplicasPerNodeGroup": "NumReplicas",
        "PreferredMaintenanceWindow": "sat:07:00-sat:08:00",
        "SecurityGroupIds": [
          "SecurityGroup"
        ],
        "SnapshotName": [
          "HasSnapshotName",
          "SnapshotName",
          "AWS::NoValue"
        ],
        "AuthToken": [
          "HasAuthToken",
          "AuthToken",
          "AWS::NoValue"
        ],
        "NumNodeGroups": "NumShards",
        "SnapshotWindow": "00:00-03:00"
      }
    }
  }
}

Positive test num. 4 - json file
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "State: ElastiCache redis, a cloudonaut.io template",
  "Resources": {
    "MyReplicationGroup": {
      "Type": "AWS::ElastiCache::ReplicationGroup",
      "Properties": {
        "ReplicationGroupDescription": "AWS::StackName",
        "AutomaticFailoverEnabled": [
          "HasAutomaticFailoverEnabled",
          true,
          false
        ],
        "EngineVersion": "EngineVersion",
        "SecurityGroupIds": [
          "SecurityGroup"
        ],
        "SnapshotName": [
          "HasSnapshotName",
          "SnapshotName",
          "AWS::NoValue"
        ],
        "AuthToken": [
          "HasAuthToken",
          "AuthToken",
          "AWS::NoValue"
        ],
        "CacheParameterGroupName": "CacheParameterGroup",
        "CacheSubnetGroupName": "CacheSubnetGroupName",
        "NumNodeGroups": "NumShards",
        "PreferredMaintenanceWindow": "sat:07:00-sat:08:00",
        "SnapshotRetentionLimit": "SnapshotRetentionLimit",
        "CacheNodeType": "CacheNodeType",
        "KmsKeyId": [
          "HasKmsKey",
          {
            "Fn::ImportValue": "${ParentKmsKeyStack}-KeyId"
          },
          "AWS::NoValue"
        ],
        "NotificationTopicArn": [
          "HasAlertTopic",
          {
            "Fn::ImportValue": "${ParentAlertStack}-TopicARN"
          },
          "AWS::NoValue"
        ],
        "ReplicasPerNodeGroup": "NumReplicas",
        "Engine": "redis",
        "SnapshotWindow": "00:00-03:00",
        "TransitEncryptionEnabled": "TransitEncryption"
      },
      "UpdatePolicy": {
        "UseOnlineResharding": true
      },
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot"
    }
  }
}

Code samples without security vulnerabilities

Negative test num. 1 - yaml file
AWSTemplateFormatVersion: '2010-09-09'
Description: 'State: ElastiCache redis, a cloudonaut.io template'
Resources:
  ReplicationGroup:
    DeletionPolicy: Snapshot
    UpdateReplacePolicy: Snapshot
    Type: AWS::ElastiCache::ReplicationGroup
    Properties:
      ReplicationGroupDescription: !Ref 'AWS::StackName'
      AtRestEncryptionEnabled: true
      AuthToken: !If [HasAuthToken, !Ref AuthToken, !Ref 'AWS::NoValue']
      AutomaticFailoverEnabled: !If [HasAutomaticFailoverEnabled, true, false]
      CacheNodeType: !Ref CacheNodeType
      CacheParameterGroupName: !Ref CacheParameterGroup
      CacheSubnetGroupName: !Ref CacheSubnetGroupName
      Engine: redis
      EngineVersion: !Ref EngineVersion
      KmsKeyId: !If [HasKmsKey, {'Fn::ImportValue': !Sub '${ParentKmsKeyStack}-KeyId'}, !Ref 'AWS::NoValue']
      NotificationTopicArn: !If [HasAlertTopic, {'Fn::ImportValue': !Sub '${ParentAlertStack}-TopicARN'}, !Ref 'AWS::NoValue']
      NumNodeGroups: !Ref NumShards
      ReplicasPerNodeGroup: !Ref NumReplicas
      PreferredMaintenanceWindow: 'sat:07:00-sat:08:00'
      SecurityGroupIds:
      - !Ref SecurityGroup
      SnapshotName: !If [HasSnapshotName, !Ref SnapshotName, !Ref 'AWS::NoValue']
      SnapshotRetentionLimit: !Ref SnapshotRetentionLimit
      SnapshotWindow: '00:00-03:00'
      TransitEncryptionEnabled: !Ref TransitEncryption
    UpdatePolicy:
      UseOnlineResharding: true
Negative test num. 2 - json file
{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "State: ElastiCache redis, a cloudonaut.io template",
  "Resources": {
    "ReplicationGroup": {
      "Properties": {
        "CacheParameterGroupName": "CacheParameterGroup",
        "EngineVersion": "EngineVersion",
        "KmsKeyId": [
          "HasKmsKey",
          {
            "Fn::ImportValue": "${ParentKmsKeyStack}-KeyId"
          },
          "AWS::NoValue"
        ],
        "ReplicasPerNodeGroup": "NumReplicas",
        "AuthToken": [
          "HasAuthToken",
          "AuthToken",
          "AWS::NoValue"
        ],
        "CacheNodeType": "CacheNodeType",
        "CacheSubnetGroupName": "CacheSubnetGroupName",
        "NotificationTopicArn": [
          "HasAlertTopic",
          {
            "Fn::ImportValue": "${ParentAlertStack}-TopicARN"
          },
          "AWS::NoValue"
        ],
        "SnapshotWindow": "00:00-03:00",
        "AutomaticFailoverEnabled": [
          "HasAutomaticFailoverEnabled",
          true,
          false
        ],
        "Engine": "redis",
        "NumNodeGroups": "NumShards",
        "SnapshotRetentionLimit": "SnapshotRetentionLimit",
        "ReplicationGroupDescription": "AWS::StackName",
        "PreferredMaintenanceWindow": "sat:07:00-sat:08:00",
        "SecurityGroupIds": [
          "SecurityGroup"
        ],
        "SnapshotName": [
          "HasSnapshotName",
          "SnapshotName",
          "AWS::NoValue"
        ],
        "TransitEncryptionEnabled": "TransitEncryption",
        "AtRestEncryptionEnabled": true
      },
      "UpdatePolicy": {
        "UseOnlineResharding": true
      },
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot",
      "Type": "AWS::ElastiCache::ReplicationGroup"
    }
  }
}