ElastiCache With Disabled Transit Encryption

  • Query id: 3b02569b-fc6f-4153-b3a3-ba91022fed68
  • Query name: ElastiCache With Disabled Transit Encryption
  • Platform: CloudFormation
  • Severity: High
  • Category: Encryption
  • URL: Github

Description

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

Code samples

Code samples with security vulnerabilities

Positive test num. 1 - yaml file
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'
    UpdatePolicy:
      UseOnlineResharding: true
Positive test num. 2 - yaml file
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
      AtRestEncryptionEnabled: true
      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: false
    UpdatePolicy:
      UseOnlineResharding: true
Positive test num. 3 - json file
{
  "Resources": {
    "ReplicationGroup": {
      "Properties": {
        "Engine": "redis",
        "EngineVersion": "EngineVersion",
        "ReplicasPerNodeGroup": "NumReplicas",
        "PreferredMaintenanceWindow": "sat:07:00-sat:08:00",
        "AtRestEncryptionEnabled": true,
        "CacheParameterGroupName": "CacheParameterGroup",
        "NotificationTopicArn": [
          "HasAlertTopic",
          {
            "Fn::ImportValue": "${ParentAlertStack}-TopicARN"
          },
          "AWS::NoValue"
        ],
        "SecurityGroupIds": [
          "SecurityGroup"
        ],
        "SnapshotName": [
          "HasSnapshotName",
          "SnapshotName",
          "AWS::NoValue"
        ],
        "SnapshotRetentionLimit": "SnapshotRetentionLimit",
        "CacheNodeType": "CacheNodeType",
        "AutomaticFailoverEnabled": [
          "HasAutomaticFailoverEnabled",
          true,
          false
        ],
        "CacheSubnetGroupName": "CacheSubnetGroupName",
        "KmsKeyId": [
          "HasKmsKey",
          {
            "Fn::ImportValue": "${ParentKmsKeyStack}-KeyId"
          },
          "AWS::NoValue"
        ],
        "NumNodeGroups": "NumShards",
        "AuthToken": [
          "HasAuthToken",
          "AuthToken",
          "AWS::NoValue"
        ],
        "SnapshotWindow": "00:00-03:00",
        "ReplicationGroupDescription": "AWS::StackName"
      },
      "UpdatePolicy": {
        "UseOnlineResharding": true
      },
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot",
      "Type": "AWS::ElastiCache::ReplicationGroup"
    }
  }
}

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

Code samples without security vulnerabilities

Negative test num. 1 - yaml file
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: true
    UpdatePolicy:
      UseOnlineResharding: true
Negative test num. 2 - json file
{
  "Resources": {
    "ReplicationGroup": {
      "UpdatePolicy": {
        "UseOnlineResharding": true
      },
      "DeletionPolicy": "Snapshot",
      "UpdateReplacePolicy": "Snapshot",
      "Type": "AWS::ElastiCache::ReplicationGroup",
      "Properties": {
        "AuthToken": [
          "HasAuthToken",
          "AuthToken",
          "AWS::NoValue"
        ],
        "AutomaticFailoverEnabled": [
          "HasAutomaticFailoverEnabled",
          true,
          false
        ],
        "SecurityGroupIds": [
          "SecurityGroup"
        ],
        "TransitEncryptionEnabled": true,
        "SnapshotWindow": "00:00-03:00",
        "CacheParameterGroupName": "CacheParameterGroup",
        "CacheSubnetGroupName": "CacheSubnetGroupName",
        "Engine": "redis",
        "EngineVersion": "EngineVersion",
        "KmsKeyId": [
          "HasKmsKey",
          {
            "Fn::ImportValue": "${ParentKmsKeyStack}-KeyId"
          },
          "AWS::NoValue"
        ],
        "SnapshotRetentionLimit": "SnapshotRetentionLimit",
        "ReplicationGroupDescription": "AWS::StackName",
        "ReplicasPerNodeGroup": "NumReplicas",
        "PreferredMaintenanceWindow": "sat:07:00-sat:08:00",
        "SnapshotName": [
          "HasSnapshotName",
          "SnapshotName",
          "AWS::NoValue"
        ],
        "AtRestEncryptionEnabled": true,
        "CacheNodeType": "CacheNodeType",
        "NotificationTopicArn": [
          "HasAlertTopic",
          {
            "Fn::ImportValue": "${ParentAlertStack}-TopicARN"
          },
          "AWS::NoValue"
        ],
        "NumNodeGroups": "NumShards"
      }
    }
  }
}