From 9c5220ee98c323ecccf3537a66fd9e4d4fb1166c Mon Sep 17 00:00:00 2001 From: Prowler Bot Date: Wed, 26 Feb 2025 12:12:44 +0100 Subject: [PATCH] fix(elasticache): improve logic in `elasticache_redis_cluster_backup_enabled` (#7045) Co-authored-by: Daniel Barranquero <74871504+danibarranqueroo@users.noreply.github.com> Co-authored-by: Sergio Garcia --- docs/tutorials/configuration_file.md | 1 + prowler/config/config.yaml | 5 ++ ...lasticache_redis_cluster_backup_enabled.py | 2 +- tests/config/config_test.py | 1 + tests/config/fixtures/config.yaml | 5 ++ ...cache_redis_cluster_backup_enabled_test.py | 48 +++++++++++++++++++ 6 files changed, 61 insertions(+), 1 deletion(-) diff --git a/docs/tutorials/configuration_file.md b/docs/tutorials/configuration_file.md index b638728b27..1b8ab29d5f 100644 --- a/docs/tutorials/configuration_file.md +++ b/docs/tutorials/configuration_file.md @@ -47,6 +47,7 @@ The following list includes all the AWS checks with configurable variables that | `ecr_repositories_scan_vulnerabilities_in_latest_image` | `ecr_repository_vulnerability_minimum_severity` | String | | `eks_cluster_uses_a_supported_version` | `eks_cluster_oldest_version_supported` | String | | `eks_control_plane_logging_all_types_enabled` | `eks_required_log_types` | List of Strings | +| `elasticache_redis_cluster_backup_enabled` | `minimum_snapshot_retention_period` | Integer | | `elb_is_in_multiple_az` | `elb_min_azs` | Integer | | `elbv2_is_in_multiple_az` | `elbv2_min_azs` | Integer | | `guardduty_is_enabled` | `mute_non_default_regions` | Boolean | diff --git a/prowler/config/config.yaml b/prowler/config/config.yaml index e319f4a029..b0280ff2d0 100644 --- a/prowler/config/config.yaml +++ b/prowler/config/config.yaml @@ -360,6 +360,11 @@ aws: # Minimum number of Availability Zones that an ELBv2 must be in elbv2_min_azs: 2 + # AWS Elasticache Configuration + # aws.elasticache_redis_cluster_backup_enabled + # Minimum number of days that a Redis cluster must have backups retention period + minimum_snapshot_retention_period: 7 + # AWS Secrets Configuration # Patterns to ignore in the secrets checks diff --git a/prowler/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled.py b/prowler/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled.py index 5639b322e8..7646856ef8 100644 --- a/prowler/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled.py +++ b/prowler/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled.py @@ -11,7 +11,7 @@ class elasticache_redis_cluster_backup_enabled(Check): report = Check_Report_AWS(metadata=self.metadata(), resource=repl_group) report.status = "FAIL" report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does not have automated snapshot backups enabled." - if repl_group.snapshot_retention > elasticache_client.audit_config.get( + if repl_group.snapshot_retention >= elasticache_client.audit_config.get( "minimum_snapshot_retention_period", 7 ): report.status = "PASS" diff --git a/tests/config/config_test.py b/tests/config/config_test.py index 6ae22e99c1..0573e0c19a 100644 --- a/tests/config/config_test.py +++ b/tests/config/config_test.py @@ -308,6 +308,7 @@ config_aws = { ], "eks_cluster_oldest_version_supported": "1.28", "excluded_sensitive_environment_variables": [], + "minimum_snapshot_retention_period": 7, "elb_min_azs": 2, "elbv2_min_azs": 2, "secrets_ignore_patterns": [], diff --git a/tests/config/fixtures/config.yaml b/tests/config/fixtures/config.yaml index fda3de68e5..a4ad182fbe 100644 --- a/tests/config/fixtures/config.yaml +++ b/tests/config/fixtures/config.yaml @@ -353,6 +353,11 @@ aws: # Minimum number of Availability Zones that an ELBv2 must be in elbv2_min_azs: 2 + # AWS Elasticache Configuration + # aws.elasticache_redis_cluster_backup_enabled + # Minimum number of days that a Redis cluster must have backups retention period + minimum_snapshot_retention_period: 7 + # AWS Secrets Configuration # Patterns to ignore in the secrets checks secrets_ignore_patterns: [] diff --git a/tests/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled_test.py b/tests/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled_test.py index a2806ad017..881db612fb 100644 --- a/tests/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled_test.py +++ b/tests/providers/aws/services/elasticache/elasticache_redis_cluster_backup_enabled/elasticache_redis_cluster_backup_enabled_test.py @@ -149,6 +149,54 @@ class Test_elasticache_redis_cluster_backup_enabled: assert result[0].resource_arn == REPLICATION_GROUP_ARN assert result[0].resource_tags == REPLICATION_GROUP_TAGS + def test_elasticache_redis_cluster_backup_enabled_7_days(self): + # Mock ElastiCache Service + elasticache_client = MagicMock + elasticache_client.replication_groups = {} + + elasticache_client.replication_groups[REPLICATION_GROUP_ARN] = ReplicationGroup( + arn=REPLICATION_GROUP_ARN, + id=REPLICATION_GROUP_ID, + region=AWS_REGION_US_EAST_1, + status=REPLICATION_GROUP_STATUS, + snapshot_retention=7, + encrypted=REPLICATION_GROUP_ENCRYPTION, + transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION, + multi_az=REPLICATION_GROUP_MULTI_AZ, + tags=REPLICATION_GROUP_TAGS, + auto_minor_version_upgrade=not AUTO_MINOR_VERSION_UPGRADE, + automatic_failover=AUTOMATIC_FAILOVER, + engine_version="6.0", + auth_token_enabled=False, + ) + + elasticache_client.audit_config = {"minimum_snapshot_retention_period": 7} + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]), + ), mock.patch( + "prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache", + new=elasticache_client, + ): + from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_backup_enabled.elasticache_redis_cluster_backup_enabled import ( + elasticache_redis_cluster_backup_enabled, + ) + + check = elasticache_redis_cluster_backup_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has automated snapshot backups enabled with retention period 7 days." + ) + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_id == REPLICATION_GROUP_ID + assert result[0].resource_arn == REPLICATION_GROUP_ARN + assert result[0].resource_tags == REPLICATION_GROUP_TAGS + def test_elasticache_redis_cluster_backup_enabled_modified_retention(self): # Mock ElastiCache Service elasticache_client = MagicMock