From 761c97100af304b69f575f71f3f71e9c81ba7f93 Mon Sep 17 00:00:00 2001 From: Daniel Barranquero Date: Thu, 12 Jun 2025 12:35:40 +0200 Subject: [PATCH] chore(aws): change fixers structure --- .../accessanalyzer_enabled_fixer.py | 4 +- ...ositories_not_publicly_accessible_fixer.py | 84 +++++++---- ...acier_vaults_policy_public_access_fixer.py | 84 +++++++---- .../guardduty_is_enabled_fixer.py | 79 +++++++---- ..._passwords_within_90_days_or_less_fixer.py | 102 +++++++++----- .../iam_password_policy_lowercase_fixer.py | 102 +++++++++----- ...password_policy_minimum_length_14_fixer.py | 102 +++++++++----- .../iam_password_policy_number_fixer.py | 102 +++++++++----- .../iam_password_policy_reuse_24_fixer.py | 102 +++++++++----- .../iam_password_policy_symbol_fixer.py | 102 +++++++++----- .../iam_password_policy_uppercase_fixer.py | 102 +++++++++----- .../kms_cmk_rotation_enabled_fixer.py | 82 +++++++---- .../neptune_cluster_public_snapshot_fixer.py | 92 +++++++----- ...e_domains_not_publicly_accessible_fixer.py | 88 +++++++----- .../rds_instance_no_public_access_fixer.py | 92 +++++++----- .../rds_snapshots_public_access_fixer.py | 132 +++++++++++------- ...ccount_level_public_access_blocks_fixer.py | 92 +++++++----- ...bucket_policy_public_write_access_fixer.py | 84 +++++++---- .../s3_bucket_public_access_fixer.py | 100 ++++++++----- .../s3_bucket_public_list_acl_fixer.py | 88 +++++++----- .../s3_bucket_public_write_acl_fixer.py | 84 +++++++---- .../securityhub_enabled_fixer.py | 87 ++++++++---- ...qs_queues_not_publicly_accessible_fixer.py | 131 +++++++++-------- ...ries_not_publicly_accessible_fixer_test.py | 23 +-- ..._vaults_policy_public_access_fixer_test.py | 14 +- .../guardduty_is_enabled_fixer_test.py | 10 +- ...words_within_90_days_or_less_fixer_test.py | 8 +- ...am_password_policy_lowercase_fixer_test.py | 6 +- ...ord_policy_minimum_length_14_fixer_test.py | 8 +- .../iam_password_policy_number_fixer_test.py | 6 +- ...iam_password_policy_reuse_24_fixer_test.py | 6 +- .../iam_password_policy_symbol_fixer_test.py | 5 +- ...am_password_policy_uppercase_fixer_test.py | 5 +- .../kms_cmk_rotation_enabled_fixer_test.py | 5 +- ...tune_cluster_public_snapshot_fixer_test.py | 12 +- ...ains_not_publicly_accessible_fixer_test.py | 17 ++- ...ds_instance_no_public_access_fixer_test.py | 21 ++- .../rds_snapshots_public_access_fixer_test.py | 27 ++-- ...t_level_public_access_blocks_fixer_test.py | 5 +- ...t_policy_public_write_access_fixer_test.py | 12 +- .../s3_bucket_public_access_fixer_test.py | 28 ++-- .../s3_bucket_public_list_acl_fixer_test.py | 50 +++++-- .../s3_bucket_public_write_acl_fixer_test.py | 50 +++++-- .../securityhub_enabled_fixer_test.py | 7 +- ...eues_not_publicly_accessible_fixer_test.py | 19 ++- 45 files changed, 1562 insertions(+), 899 deletions(-) diff --git a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_fixer.py b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_fixer.py index 24b020ce6c..3c02b45508 100644 --- a/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_fixer.py +++ b/prowler/providers/aws/services/accessanalyzer/accessanalyzer_enabled/accessanalyzer_enabled_fixer.py @@ -16,8 +16,8 @@ class AccessAnalyzerEnabledFixer(AWSFixer): def __init__(self): super().__init__( description="Enable Access Analyzer in a region", - cost_impact=False, - cost_description=None, + cost_impact=True, + cost_description="Enabling Access Analyzer may incur costs for policy and resource analysis, especially in large accounts or organizations. See AWS Access Analyzer pricing.", service="accessanalyzer", iam_policy_required={ "Version": "2012-10-17", diff --git a/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py b/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py index 6c43385e73..acd56d924e 100644 --- a/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py +++ b/prowler/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer.py @@ -1,38 +1,62 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.ecr.ecr_client import ecr_client -def fixer(resource_id: str, region: str) -> bool: +class EcrRepositoriesNotPubliclyAccessibleFixer(AWSFixer): """ - Modify the ECR repository's policy to remove public access. - Specifically, this fixer delete the policy that had public access. - Requires the ecr:DeleteRepositoryPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "ecr:DeleteRepositoryPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The ECR repository name. - region (str): AWS region where the ECR repository exists. - Returns: - bool: True if the operation is successful (policy updated), False otherwise. + Fixer to remove public access from ECR repositories by deleting their policy. """ - try: - regional_client = ecr_client.regional_clients[region] - regional_client.delete_repository_policy(repositoryName=resource_id) - - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + def __init__(self): + super().__init__( + description="Remove public access from ECR repositories by deleting their policy.", + cost_impact=False, + cost_description=None, + service="ecr", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "ecr:DeleteRepositoryPolicy", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public access from ECR repositories by deleting their policy. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id, region (if finding is not provided) + Returns: + bool: True if the operation is successful (policy updated), False otherwise. + """ + try: + if finding: + resource_id = finding.resource_id + region = finding.region + else: + resource_id = kwargs.get("resource_id") + region = kwargs.get("region") + + if not resource_id or not region: + raise ValueError("resource_id and region are required") + + super().fix(region=region) + + regional_client = ecr_client.regional_clients[region] + regional_client.delete_repository_policy(repositoryName=resource_id) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer.py b/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer.py index c9362e07bf..e20acd1cb9 100644 --- a/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer.py +++ b/prowler/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer.py @@ -1,38 +1,62 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.glacier.glacier_client import glacier_client -def fixer(resource_id: str, region: str) -> bool: +class GlacierVaultsPolicyPublicAccessFixer(AWSFixer): """ - Modify the Glacier vault's policy to remove public access. - Specifically, this fixer delete the vault policy that has public access. - Requires the glacier:DeleteVaultAccessPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "glacier:DeleteVaultAccessPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The Glacier vault name. - region (str): AWS region where the Glacier vault exists. - Returns: - bool: True if the operation is successful (policy updated), False otherwise. + Fixer to remove public access from Glacier vaults by deleting their access policy. """ - try: - regional_client = glacier_client.regional_clients[region] - regional_client.delete_vault_access_policy(vaultName=resource_id) - - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + def __init__(self): + super().__init__( + description="Remove public access from Glacier vaults by deleting their access policy.", + cost_impact=False, + cost_description=None, + service="glacier", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "glacier:DeleteVaultAccessPolicy", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public access from Glacier vaults by deleting their access policy. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id, region (if finding is not provided) + Returns: + bool: True if the operation is successful (policy updated), False otherwise. + """ + try: + if finding: + resource_id = finding.resource_id + region = finding.region + else: + resource_id = kwargs.get("resource_id") + region = kwargs.get("region") + + if not resource_id or not region: + raise ValueError("resource_id and region are required") + + super().fix(region=region) + + regional_client = glacier_client.regional_clients[region] + regional_client.delete_vault_access_policy(vaultName=resource_id) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer.py b/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer.py index c9556c2905..8d9ad6b40a 100644 --- a/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer.py +++ b/prowler/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer.py @@ -1,33 +1,60 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.guardduty.guardduty_client import guardduty_client -def fixer(region): +class GuarddutyIsEnabledFixer(AWSFixer): """ - Enable GuardDuty in a region. Requires the guardduty:CreateDetector permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "guardduty:CreateDetector", - "Resource": "*" - } - ] - } - Args: - region (str): AWS region - Returns: - bool: True if GuardDuty is enabled, False otherwise + Fixer to enable GuardDuty in a region. """ - try: - regional_client = guardduty_client.regional_clients[region] - regional_client.create_detector(Enable=True) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + + def __init__(self): + super().__init__( + description="Enable GuardDuty in a region.", + cost_impact=True, + cost_description="Enabling GuardDuty incurs costs based on the volume of logs and events analyzed. Charges apply per GB of data processed and for threat detection features. See AWS GuardDuty pricing.", + service="guardduty", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "guardduty:CreateDetector", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable GuardDuty in a region. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region (if finding is not provided) + Returns: + bool: True if GuardDuty is enabled, False otherwise + """ + try: + if finding: + region = finding.region + else: + region = kwargs.get("region") + + if not region: + raise ValueError("region is required") + + super().fix(region=region) + + regional_client = guardduty_client.regional_clients[region] + regional_client.create_detector(Enable=True) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer.py index 0643e48077..c898e74706 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicyExpiresPasswordsWithin90DaysOrLessFixer(AWSFixer): """ - Enable IAM password policy to expire passwords within 90 days or less or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to expire passwords within 90 days or less (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.password_policy.length, - RequireSymbols=iam_client.password_policy.symbols, - RequireNumbers=iam_client.password_policy.numbers, - RequireUppercaseCharacters=iam_client.password_policy.uppercase, - RequireLowercaseCharacters=iam_client.password_policy.lowercase, - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.fixer_config.get("iam_password_policy", {}).get( - "MaxPasswordAge", 90 - ), - PasswordReusePrevention=iam_client.password_policy.reuse_prevention, - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to expire passwords within 90 days or less (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to expire passwords within 90 days or less (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.password_policy.length, + RequireSymbols=iam_client.password_policy.symbols, + RequireNumbers=iam_client.password_policy.numbers, + RequireUppercaseCharacters=iam_client.password_policy.uppercase, + RequireLowercaseCharacters=iam_client.password_policy.lowercase, + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("MaxPasswordAge", 90), + PasswordReusePrevention=iam_client.password_policy.reuse_prevention, + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer.py index 6372e30b65..29093d0dcd 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicyLowercaseFixer(AWSFixer): """ - Enable IAM password policy to require lowercase characters or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to require lowercase characters (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.password_policy.length, - RequireSymbols=iam_client.password_policy.symbols, - RequireNumbers=iam_client.password_policy.numbers, - RequireUppercaseCharacters=iam_client.password_policy.uppercase, - RequireLowercaseCharacters=iam_client.fixer_config.get( - "iam_password_policy", {} - ).get("RequireLowercaseCharacters", True), - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.password_policy.max_age, - PasswordReusePrevention=iam_client.password_policy.reuse_prevention, - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to require lowercase characters (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to require lowercase characters (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.password_policy.length, + RequireSymbols=iam_client.password_policy.symbols, + RequireNumbers=iam_client.password_policy.numbers, + RequireUppercaseCharacters=iam_client.password_policy.uppercase, + RequireLowercaseCharacters=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("RequireLowercaseCharacters", True), + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.password_policy.max_age, + PasswordReusePrevention=iam_client.password_policy.reuse_prevention, + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer.py index 85a14c3bac..59c0f2b539 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicyMinimumLength14Fixer(AWSFixer): """ - Enable IAM password policy to require a minimum password length of 14 characters or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to require a minimum password length of 14 characters (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.fixer_config.get( - "iam_password_policy", {} - ).get("MinimumPasswordLength", 14), - RequireSymbols=iam_client.password_policy.symbols, - RequireNumbers=iam_client.password_policy.numbers, - RequireUppercaseCharacters=iam_client.password_policy.uppercase, - RequireLowercaseCharacters=iam_client.password_policy.lowercase, - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.password_policy.max_age, - PasswordReusePrevention=iam_client.password_policy.reuse_prevention, - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to require a minimum password length of 14 characters (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to require a minimum password length of 14 characters (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("MinimumPasswordLength", 14), + RequireSymbols=iam_client.password_policy.symbols, + RequireNumbers=iam_client.password_policy.numbers, + RequireUppercaseCharacters=iam_client.password_policy.uppercase, + RequireLowercaseCharacters=iam_client.password_policy.lowercase, + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.password_policy.max_age, + PasswordReusePrevention=iam_client.password_policy.reuse_prevention, + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer.py index 7b11d70dd7..4cf70d105b 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicyNumberFixer(AWSFixer): """ - Enable IAM password policy to require numbers or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to require numbers (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.password_policy.length, - RequireSymbols=iam_client.password_policy.symbols, - RequireNumbers=iam_client.fixer_config.get("iam_password_policy", {}).get( - "RequireNumbers", True - ), - RequireUppercaseCharacters=iam_client.password_policy.uppercase, - RequireLowercaseCharacters=iam_client.password_policy.lowercase, - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.password_policy.max_age, - PasswordReusePrevention=iam_client.password_policy.reuse_prevention, - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to require numbers (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to require numbers (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.password_policy.length, + RequireSymbols=iam_client.password_policy.symbols, + RequireNumbers=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("RequireNumbers", True), + RequireUppercaseCharacters=iam_client.password_policy.uppercase, + RequireLowercaseCharacters=iam_client.password_policy.lowercase, + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.password_policy.max_age, + PasswordReusePrevention=iam_client.password_policy.reuse_prevention, + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer.py index 1ad0ccbcaf..7c33b9e73e 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicyReuse24Fixer(AWSFixer): """ - Enable IAM password policy to prevent reusing the 24 previous passwords or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to prevent reusing the 24 previous passwords (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.password_policy.length, - RequireSymbols=iam_client.password_policy.symbols, - RequireNumbers=iam_client.password_policy.numbers, - RequireUppercaseCharacters=iam_client.password_policy.uppercase, - RequireLowercaseCharacters=iam_client.password_policy.lowercase, - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.password_policy.max_age, - PasswordReusePrevention=iam_client.fixer_config.get( - "iam_password_policy", {} - ).get("PasswordReusePrevention", 24), - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to prevent reusing the 24 previous passwords (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to prevent reusing the 24 previous passwords (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.password_policy.length, + RequireSymbols=iam_client.password_policy.symbols, + RequireNumbers=iam_client.password_policy.numbers, + RequireUppercaseCharacters=iam_client.password_policy.uppercase, + RequireLowercaseCharacters=iam_client.password_policy.lowercase, + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.password_policy.max_age, + PasswordReusePrevention=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("PasswordReusePrevention", 24), + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer.py index 4fa6bf6ee8..c921d492eb 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicySymbolFixer(AWSFixer): """ - Enable IAM password policy to require symbols or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to require symbols (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.password_policy.length, - RequireSymbols=iam_client.fixer_config.get("iam_password_policy", {}).get( - "RequireSymbols", True - ), - RequireNumbers=iam_client.password_policy.numbers, - RequireUppercaseCharacters=iam_client.password_policy.uppercase, - RequireLowercaseCharacters=iam_client.password_policy.lowercase, - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.password_policy.max_age, - PasswordReusePrevention=iam_client.password_policy.reuse_prevention, - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to require symbols (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to require symbols (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.password_policy.length, + RequireSymbols=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("RequireSymbols", True), + RequireNumbers=iam_client.password_policy.numbers, + RequireUppercaseCharacters=iam_client.password_policy.uppercase, + RequireLowercaseCharacters=iam_client.password_policy.lowercase, + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.password_policy.max_age, + PasswordReusePrevention=iam_client.password_policy.reuse_prevention, + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer.py b/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer.py index 4723cd9dcd..18bcddaac9 100644 --- a/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer.py +++ b/prowler/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer.py @@ -1,45 +1,71 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.iam.iam_client import iam_client -def fixer(resource_id: str) -> bool: +class IamPasswordPolicyUppercaseFixer(AWSFixer): """ - Enable IAM password policy to require uppercase characters or the configurable value in prowler/config/fixer_config.yaml. - Requires the iam:UpdateAccountPasswordPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "iam:UpdateAccountPasswordPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): AWS account ID - Returns: - bool: True if IAM password policy is updated, False otherwise + Fixer to enable IAM password policy to require uppercase characters (or configurable value). """ - try: - iam_client.client.update_account_password_policy( - MinimumPasswordLength=iam_client.password_policy.length, - RequireSymbols=iam_client.password_policy.symbols, - RequireNumbers=iam_client.password_policy.numbers, - RequireUppercaseCharacters=iam_client.fixer_config.get( - "iam_password_policy", {} - ).get("RequireUppercaseCharacters", True), - RequireLowercaseCharacters=iam_client.password_policy.lowercase, - AllowUsersToChangePassword=iam_client.password_policy.allow_change, - MaxPasswordAge=iam_client.password_policy.max_age, - PasswordReusePrevention=iam_client.password_policy.reuse_prevention, - HardExpiry=iam_client.password_policy.hard_expiry, + + def __init__(self): + super().__init__( + description="Enable IAM password policy to require uppercase characters (or configurable value).", + cost_impact=False, + cost_description=None, + service="iam", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "iam:UpdateAccountPasswordPolicy", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable IAM password policy to require uppercase characters (or configurable value). + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if IAM password policy is updated, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + iam_client.client.update_account_password_policy( + MinimumPasswordLength=iam_client.password_policy.length, + RequireSymbols=iam_client.password_policy.symbols, + RequireNumbers=iam_client.password_policy.numbers, + RequireUppercaseCharacters=iam_client.fixer_config.get( + "iam_password_policy", {} + ).get("RequireUppercaseCharacters", True), + RequireLowercaseCharacters=iam_client.password_policy.lowercase, + AllowUsersToChangePassword=iam_client.password_policy.allow_change, + MaxPasswordAge=iam_client.password_policy.max_age, + PasswordReusePrevention=iam_client.password_policy.reuse_prevention, + HardExpiry=iam_client.password_policy.hard_expiry, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer.py b/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer.py index 5387af8ad7..c7ea6ceb53 100644 --- a/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer.py +++ b/prowler/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer.py @@ -1,34 +1,62 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.kms.kms_client import kms_client -def fixer(resource_id: str, region: str) -> bool: +class KmsCmkRotationEnabledFixer(AWSFixer): """ - Enable CMK rotation. Requires the kms:EnableKeyRotation permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "kms:EnableKeyRotation", - "Resource": "*" - } - ] - } - Args: - resource_id (str): KMS CMK ID - region (str): AWS region - Returns: - bool: True if CMK rotation is enabled, False otherwise + Fixer to enable CMK rotation. """ - try: - regional_client = kms_client.regional_clients[region] - regional_client.enable_key_rotation(KeyId=resource_id) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + + def __init__(self): + super().__init__( + description="Enable CMK rotation.", + cost_impact=False, + cost_description=None, + service="kms", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "kms:EnableKeyRotation", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable CMK rotation. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if CMK rotation is enabled, False otherwise + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = kms_client.regional_clients[region] + regional_client.enable_key_rotation(KeyId=resource_id) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer.py b/prowler/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer.py index d7c4ecef3c..85cd36685a 100644 --- a/prowler/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer.py +++ b/prowler/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer.py @@ -1,40 +1,66 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.neptune.neptune_client import neptune_client -def fixer(resource_id: str, region: str) -> bool: +class NeptuneClusterPublicSnapshotFixer(AWSFixer): """ - Modify the attributes of a Neptune DB cluster snapshot to remove public access. - Specifically, this fixer removes the 'all' value from the 'restore' attribute to - prevent the snapshot from being publicly accessible. Requires the rds:ModifyDBClusterSnapshotAttribute permissions. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "rds:ModifyDBClusterSnapshotAttribute", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The DB cluster snapshot identifier. - region (str): AWS region where the snapshot exists. - Returns: - bool: True if the operation is successful (public access is removed), False otherwise. + Fixer to remove public access from Neptune DB cluster snapshots. """ - try: - regional_client = neptune_client.regional_clients[region] - regional_client.modify_db_cluster_snapshot_attribute( - DBClusterSnapshotIdentifier=resource_id, - AttributeName="restore", - ValuesToRemove=["all"], + + def __init__(self): + super().__init__( + description="Remove public access from Neptune DB cluster snapshots.", + cost_impact=False, + cost_description=None, + service="neptune", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "rds:ModifyDBClusterSnapshotAttribute", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public access from Neptune DB cluster snapshots. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if public access is removed, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = neptune_client.regional_clients[region] + regional_client.modify_db_cluster_snapshot_attribute( + DBClusterSnapshotIdentifier=resource_id, + AttributeName="restore", + ValuesToRemove=["all"], + ) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer.py b/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer.py index a43a94fc6e..f50ba7b3b2 100644 --- a/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer.py +++ b/prowler/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer.py @@ -1,43 +1,67 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.opensearch.opensearch_client import ( opensearch_client, ) -def fixer(resource_id: str, region: str) -> bool: +class OpensearchServiceDomainsNotPubliclyAccessibleFixer(AWSFixer): """ - Modify the OpenSearch domain's resource-based policy to remove public access. - Specifically, this fixer update the domain config and add an empty policy to remove the old one. - Requires the es:UpdateDomainConfig permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "es:UpdateDomainConfig", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The OpenSearch domain name. - region (str): AWS region where the OpenSearch domain exists. - Returns: - bool: True if the operation is successful (policy updated), False otherwise. + Fixer to remove public access from OpenSearch domains. """ - try: - regional_client = opensearch_client.regional_clients[region] - regional_client.update_domain_config( - DomainName=resource_id, - AccessPolicies="", + def __init__(self): + super().__init__( + description="Remove public access from OpenSearch domains.", + cost_impact=False, + cost_description=None, + service="opensearch", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "es:UpdateDomainConfig", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public access from OpenSearch domains. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if public access is removed, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = opensearch_client.regional_clients[region] + regional_client.update_domain_config( + DomainName=resource_id, + AccessPolicies="", + ) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py b/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py index e15f7325b8..34a17fca41 100644 --- a/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py +++ b/prowler/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer.py @@ -1,40 +1,66 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.rds.rds_client import rds_client -def fixer(resource_id: str, region: str) -> bool: +class RdsInstanceNoPublicAccessFixer(AWSFixer): """ - Modify the attributes of an RDS instance to disable public accessibility. - Specifically, this fixer sets the 'PubliclyAccessible' attribute to False - to prevent the RDS instance from being publicly accessible. Requires the rds:ModifyDBInstance permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "rds:ModifyDBInstance", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The DB instance identifier. - region (str): AWS region where the DB instance exists. - Returns: - bool: True if the operation is successful (public access is disabled), False otherwise. + Fixer to disable public accessibility for RDS instances. """ - try: - regional_client = rds_client.regional_clients[region] - regional_client.modify_db_instance( - DBInstanceIdentifier=resource_id, - PubliclyAccessible=False, - ApplyImmediately=True, + + def __init__(self): + super().__init__( + description="Disable public accessibility for RDS instances.", + cost_impact=False, + cost_description=None, + service="rds", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "rds:ModifyDBInstance", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Disable public accessibility for RDS instances. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if public access is disabled, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = rds_client.regional_clients[region] + regional_client.modify_db_instance( + DBInstanceIdentifier=resource_id, + PubliclyAccessible=False, + ApplyImmediately=True, + ) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer.py b/prowler/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer.py index 57ede076c0..ec5e6e37af 100644 --- a/prowler/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer.py +++ b/prowler/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer.py @@ -1,60 +1,86 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.rds.rds_client import rds_client -def fixer(resource_id: str, region: str) -> bool: +class RdsSnapshotsPublicAccessFixer(AWSFixer): """ - Modify the attributes of an RDS DB snapshot or DB cluster snapshot to remove public access. - Specifically, this fixer removes the 'all' value from the 'restore' attribute to prevent the snapshot from being publicly accessible - for both DB snapshots and DB cluster snapshots. Requires the rds:ModifyDBSnapshotAttribute or rds:ModifyDBClusterSnapshotAttribute permissions. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "rds:ModifyDBSnapshotAttribute", - "Resource": "*" + Fixer to remove public access from RDS DB snapshots and DB cluster snapshots. + """ + + def __init__(self): + super().__init__( + description="Remove public access from RDS DB snapshots and DB cluster snapshots.", + cost_impact=False, + cost_description=None, + service="rds", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "rds:ModifyDBSnapshotAttribute", + "Resource": "*", + }, + { + "Effect": "Allow", + "Action": "rds:ModifyDBClusterSnapshotAttribute", + "Resource": "*", + }, + ], }, - { - "Effect": "Allow", - "Action": "rds:ModifyDBClusterSnapshotAttribute", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The DB snapshot or DB cluster snapshot identifier. - region (str): AWS region where the snapshot exists. - Returns: - bool: True if the operation is successful (public access is removed), False otherwise. - """ - try: - regional_client = rds_client.regional_clients[region] - - # Check if the resource is a DB Cluster Snapshot or a DB Instance Snapshot - try: - regional_client.describe_db_cluster_snapshots( - DBClusterSnapshotIdentifier=resource_id - ) - # If the describe call is successful, it's a DB cluster snapshot - regional_client.modify_db_cluster_snapshot_attribute( - DBClusterSnapshotIdentifier=resource_id, - AttributeName="restore", - ValuesToRemove=["all"], - ) - except regional_client.exceptions.DBClusterSnapshotNotFoundFault: - # If the DB cluster snapshot doesn't exist, it's an instance snapshot - regional_client.modify_db_snapshot_attribute( - DBSnapshotIdentifier=resource_id, - AttributeName="restore", - ValuesToRemove=["all"], - ) - - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public access from RDS DB snapshots and DB cluster snapshots. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if public access is removed, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = rds_client.regional_clients[region] + + # Check if the resource is a DB Cluster Snapshot or a DB Instance Snapshot + try: + regional_client.describe_db_cluster_snapshots( + DBClusterSnapshotIdentifier=resource_id + ) + # If the describe call is successful, it's a DB cluster snapshot + regional_client.modify_db_cluster_snapshot_attribute( + DBClusterSnapshotIdentifier=resource_id, + AttributeName="restore", + ValuesToRemove=["all"], + ) + except regional_client.exceptions.DBClusterSnapshotNotFoundFault: + # If the DB cluster snapshot doesn't exist, it's an instance snapshot + regional_client.modify_db_snapshot_attribute( + DBSnapshotIdentifier=resource_id, + AttributeName="restore", + ValuesToRemove=["all"], + ) + + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer.py b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer.py index 6de203a3f8..b224415d0f 100644 --- a/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer.py +++ b/prowler/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer.py @@ -1,41 +1,67 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.s3.s3control_client import s3control_client -def fixer(resource_id: str) -> bool: +class S3AccountLevelPublicAccessBlocksFixer(AWSFixer): """ - Enable S3 Block Public Access for the account. NOTE: By blocking all S3 public access you may break public S3 buckets. - Requires the s3:PutAccountPublicAccessBlock permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:PutAccountPublicAccessBlock", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The AWS account ID. - Returns: - bool: True if S3 Block Public Access is enabled, False otherwise + Fixer to enable S3 Block Public Access for the account. """ - try: - s3control_client.client.put_public_access_block( - AccountId=resource_id, - PublicAccessBlockConfiguration={ - "BlockPublicAcls": True, - "IgnorePublicAcls": True, - "BlockPublicPolicy": True, - "RestrictPublicBuckets": True, + + def __init__(self): + super().__init__( + description="Enable S3 Block Public Access for the account.", + cost_impact=False, + cost_description=None, + service="s3", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:PutAccountPublicAccessBlock", + "Resource": "*", + } + ], }, ) - except Exception as error: - logger.error( - f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable S3 Block Public Access for the account. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: resource_id (account id, if finding is not provided) + Returns: + bool: True if S3 Block Public Access is enabled, False otherwise + """ + try: + if finding: + resource_id = finding.resource_id + else: + resource_id = kwargs.get("resource_id") + + if not resource_id: + raise ValueError("resource_id (account id) is required") + + super().fix() + + s3control_client.client.put_public_access_block( + AccountId=resource_id, + PublicAccessBlockConfiguration={ + "BlockPublicAcls": True, + "IgnorePublicAcls": True, + "BlockPublicPolicy": True, + "RestrictPublicBuckets": True, + }, + ) + except Exception as error: + logger.error( + f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer.py b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer.py index 4edd4b39dd..cd028f54ee 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer.py +++ b/prowler/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer.py @@ -1,38 +1,62 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.s3.s3_client import s3_client -def fixer(resource_id: str, region: str) -> bool: +class S3BucketPolicyPublicWriteAccessFixer(AWSFixer): """ - Modify the S3 bucket's policy to remove public access. - Specifically, this fixer delete the policy of the public bucket. - Requires the s3:DeleteBucketPolicy permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:DeleteBucketPolicy", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The S3 bucket name. - region (str): AWS region where the S3 bucket exists. - Returns: - bool: True if the operation is successful (policy updated), False otherwise. + Fixer to remove public write access from S3 bucket policies. """ - try: - regional_client = s3_client.regional_clients[region] - regional_client.delete_bucket_policy(Bucket=resource_id) - - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + def __init__(self): + super().__init__( + description="Remove public write access from S3 bucket policies.", + cost_impact=False, + cost_description=None, + service="s3", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:DeleteBucketPolicy", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public write access from S3 bucket policies. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if the policy is removed, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = s3_client.regional_clients[region] + regional_client.delete_bucket_policy(Bucket=resource_id) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer.py b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer.py index 693336dec9..8ca5fa9d5c 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer.py +++ b/prowler/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer.py @@ -1,46 +1,70 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.s3.s3_client import s3_client -def fixer(resource_id: str, region: str) -> bool: +class S3BucketPublicAccessFixer(AWSFixer): """ - Modify the S3 bucket's public access settings to block all public access. - Specifically, this fixer configures the bucket's public access block settings to - prevent any public access (ACLs and policies). Requires the s3:PutBucketPublicAccessBlock - permission to modify the public access settings. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:PutBucketPublicAccessBlock", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The S3 bucket name. - region (str): AWS region where the S3 bucket exists. - Returns: - bool: True if the operation is successful (public access is blocked), - False otherwise. + Fixer to block all public access to S3 buckets. """ - try: - regional_client = s3_client.regional_clients[region] - regional_client.put_public_access_block( - Bucket=resource_id, - PublicAccessBlockConfiguration={ - "BlockPublicAcls": True, - "IgnorePublicAcls": True, - "BlockPublicPolicy": True, - "RestrictPublicBuckets": True, + + def __init__(self): + super().__init__( + description="Block all public access to S3 buckets.", + cost_impact=False, + cost_description=None, + service="s3", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:PutBucketPublicAccessBlock", + "Resource": "*", + } + ], }, ) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Block all public access to S3 buckets. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if public access is blocked, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = s3_client.regional_clients[region] + regional_client.put_public_access_block( + Bucket=resource_id, + PublicAccessBlockConfiguration={ + "BlockPublicAcls": True, + "IgnorePublicAcls": True, + "BlockPublicPolicy": True, + "RestrictPublicBuckets": True, + }, + ) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer.py b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer.py index 1ab315b61d..9215cb0174 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer.py +++ b/prowler/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer.py @@ -1,40 +1,62 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.s3.s3_client import s3_client -def fixer(resource_id: str, region: str) -> bool: +class S3BucketPublicListAclFixer(AWSFixer): """ - Modify the S3 bucket ACL to restrict public read access. - Specifically, this fixer sets the ACL of the bucket to 'private' to prevent - any public access to the S3 bucket. - Requires the s3:PutBucketAcl permission. - - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:PutBucketAcl", - "Resource": "*" - } - ] - } - - Args: - resource_id (str): The S3 bucket name. - region (str): AWS region where the S3 bucket exists. - - Returns: - bool: True if the operation is successful (bucket access is updated), False otherwise. + Fixer to restrict public read access by setting the S3 bucket ACL to 'private'. """ - try: - regional_client = s3_client.regional_clients[region] - regional_client.put_bucket_acl(Bucket=resource_id, ACL="private") - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + + def __init__(self): + super().__init__( + description="Restrict public read access by setting the S3 bucket ACL to 'private'.", + cost_impact=False, + cost_description=None, + service="s3", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:PutBucketAcl", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Restrict public read access by setting the S3 bucket ACL to 'private'. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if the bucket ACL is set to private, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = s3_client.regional_clients[region] + regional_client.put_bucket_acl(Bucket=resource_id, ACL="private") + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer.py b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer.py index e27787a967..151d753497 100644 --- a/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer.py +++ b/prowler/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer.py @@ -1,36 +1,62 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.s3.s3_client import s3_client -def fixer(resource_id: str, region: str) -> bool: +class S3BucketPublicWriteAclFixer(AWSFixer): """ - Modify the S3 bucket ACL to restrict public write access. - Specifically, this fixer sets the ACL of the bucket to 'private' to prevent - public write access to the S3 bucket. Requires the s3:PutBucketAcl permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "s3:PutBucketAcl", - "Resource": "*" - } - ] - } - Args: - resource_id (str): The S3 bucket id. - region (str): AWS region where the S3 bucket exists. - Returns: - bool: True if the operation is successful (bucket access is updated), False otherwise. + Fixer to restrict public write access by setting the S3 bucket ACL to 'private'. """ - try: - regional_client = s3_client.regional_clients[region] - regional_client.put_bucket_acl(Bucket=resource_id, ACL="private") - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + + def __init__(self): + super().__init__( + description="Restrict public write access by setting the S3 bucket ACL to 'private'.", + cost_impact=False, + cost_description=None, + service="s3", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "s3:PutBucketAcl", + "Resource": "*", + } + ], + }, ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Restrict public write access by setting the S3 bucket ACL to 'private'. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if the bucket ACL is set to private, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + regional_client = s3_client.regional_clients[region] + regional_client.put_bucket_acl(Bucket=resource_id, ACL="private") + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer.py b/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer.py index aceade1da6..794c3d54ff 100644 --- a/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer.py +++ b/prowler/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer.py @@ -1,39 +1,66 @@ +from typing import Optional + +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.securityhub.securityhub_client import ( securityhub_client, ) -def fixer(region): +class SecurityhubEnabledFixer(AWSFixer): """ - Enable Security Hub in a region. Requires the securityhub:EnableSecurityHub permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "securityhub:EnableSecurityHub", - "Resource": "*" - } - ] - } - Args: - region (str): AWS region - Returns: - bool: True if Security Hub is enabled, False otherwise + Fixer to enable Security Hub in a region. """ - try: - regional_client = securityhub_client.regional_clients[region] - regional_client.enable_security_hub( - EnableDefaultStandards=securityhub_client.fixer_config.get( - "securityhub_enabled", {} - ).get("EnableDefaultStandards", True) + + def __init__(self): + super().__init__( + description="Enable Security Hub in a region.", + cost_impact=True, + cost_description="Enabling Security Hub incurs costs for findings ingestion, analysis, and resource coverage. Charges apply per finding and per resource. See AWS Security Hub pricing.", + service="securityhub", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "securityhub:EnableSecurityHub", + "Resource": "*", + } + ], + }, ) - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Enable Security Hub in a region. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region (if finding is not provided) + Returns: + bool: True if Security Hub is enabled, False otherwise + """ + try: + if finding: + region = finding.region + else: + region = kwargs.get("region") + + if not region: + raise ValueError("region is required") + + super().fix(region=region) + + regional_client = securityhub_client.regional_clients[region] + regional_client.enable_security_hub( + EnableDefaultStandards=securityhub_client.fixer_config.get( + "securityhub_enabled", {} + ).get("EnableDefaultStandards", True) + ) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer.py b/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer.py index a8e0e489d4..7fead4d13a 100644 --- a/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer.py +++ b/prowler/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer.py @@ -1,64 +1,85 @@ import json +from typing import Optional +from prowler.lib.check.models import Check_Report_AWS from prowler.lib.logger import logger +from prowler.providers.aws.lib.fix.fixer import AWSFixer from prowler.providers.aws.services.sqs.sqs_client import sqs_client -def fixer(resource_id: str, region: str) -> bool: +class SqsQueuesNotPubliclyAccessibleFixer(AWSFixer): """ - Modify the SQS queue's resource-based policy to remove public access and replace with trusted account access. - Specifically, this fixer checks if any statement has a public Principal (e.g., "*" or "CanonicalUser") - and replaces it with the ARN of the trusted AWS account. - Requires the sqs:SetQueueAttributes permission. - Permissions: - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "sqs:SetQueueAttributes", - "Resource": "*" + Fixer to remove public access from SQS queue policies and replace with trusted account access. + """ + + def __init__(self): + super().__init__( + description="Remove public access from SQS queue policies and replace with trusted account access.", + cost_impact=False, + cost_description=None, + service="sqs", + iam_policy_required={ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": "sqs:SetQueueAttributes", + "Resource": "*", + } + ], + }, + ) + + def fix(self, finding: Optional[Check_Report_AWS] = None, **kwargs) -> bool: + """ + Remove public access from SQS queue policies and replace with trusted account access. + Args: + finding (Optional[Check_Report_AWS]): Finding to fix + **kwargs: region, resource_id (if finding is not provided) + Returns: + bool: True if the policy is updated, False otherwise. + """ + try: + if finding: + region = finding.region + resource_id = finding.resource_id + else: + region = kwargs.get("region") + resource_id = kwargs.get("resource_id") + + if not region or not resource_id: + raise ValueError("region and resource_id are required") + + super().fix(region=region, resource_id=resource_id) + + account_id = sqs_client.audited_account + audited_partition = sqs_client.audited_partition + regional_client = sqs_client.regional_clients[region] + queue_name = resource_id.split("/")[-1] + + trusted_policy = { + "Version": "2012-10-17", + "Statement": [ + { + "Sid": "ProwlerFixerStatement", + "Effect": "Allow", + "Principal": { + "AWS": account_id, + }, + "Action": "sqs:*", + "Resource": f"arn:{audited_partition}:sqs:{region}:{account_id}:{queue_name}", + } + ], } - ] - } - Args: - resource_id (str): The SQS queue name or ARN. - region (str): AWS region where the SQS queue exists. - Returns: - bool: True if the operation is successful (policy updated), False otherwise. - """ - try: - account_id = sqs_client.audited_account - audited_partition = sqs_client.audited_partition - regional_client = sqs_client.regional_clients[region] - - queue_name = resource_id.split("/")[-1] - - trusted_policy = { - "Version": "2012-10-17", - "Statement": [ - { - "Sid": "ProwlerFixerStatement", - "Effect": "Allow", - "Principal": { - "AWS": account_id, - }, - "Action": "sqs:*", - "Resource": f"arn:{audited_partition}:sqs:{region}:{account_id}:{queue_name}", - } - ], - } - - regional_client.set_queue_attributes( - QueueUrl=resource_id, - Attributes={"Policy": json.dumps(trusted_policy)}, - ) - - except Exception as error: - logger.error( - f"{region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - return False - else: - return True + regional_client.set_queue_attributes( + QueueUrl=resource_id, + Attributes={"Policy": json.dumps(trusted_policy)}, + ) + except Exception as error: + logger.error( + f"{region if 'region' in locals() else 'unknown'} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + return False + else: + return True diff --git a/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py b/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py index e0e68c571f..02173923b0 100644 --- a/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py +++ b/tests/providers/aws/services/ecr/ecr_repositories_not_publicly_accessible/ecr_repositories_not_publicly_accessible_fixer_test.py @@ -7,7 +7,7 @@ from moto import mock_aws from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider -class Test_ecr_repositories_not_publicly_accessible_fixer: +class TestEcrRepositoriesNotPubliclyAccessibleFixer: @mock_aws def test_ecr_repository_public(self): ecr_client = client("ecr", region_name=AWS_REGION_EU_WEST_1) @@ -46,12 +46,13 @@ class Test_ecr_repositories_not_publicly_accessible_fixer: new=ECR(aws_provider), ), ): - # Test Fixer from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer import ( - fixer, + EcrRepositoriesNotPubliclyAccessibleFixer, ) - assert fixer(repository_name, AWS_REGION_EU_WEST_1) + assert EcrRepositoriesNotPubliclyAccessibleFixer().fix( + resource_id=repository_name, region=AWS_REGION_EU_WEST_1 + ) @mock_aws def test_ecr_repository_not_public(self): @@ -91,12 +92,13 @@ class Test_ecr_repositories_not_publicly_accessible_fixer: new=ECR(aws_provider), ), ): - # Test Fixer from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer import ( - fixer, + EcrRepositoriesNotPubliclyAccessibleFixer, ) - assert fixer(repository_name, AWS_REGION_EU_WEST_1) + assert EcrRepositoriesNotPubliclyAccessibleFixer().fix( + resource_id=repository_name, region=AWS_REGION_EU_WEST_1 + ) @mock_aws def test_ecr_repository_public_error(self): @@ -136,9 +138,10 @@ class Test_ecr_repositories_not_publicly_accessible_fixer: new=ECR(aws_provider), ), ): - # Test Fixer from prowler.providers.aws.services.ecr.ecr_repositories_not_publicly_accessible.ecr_repositories_not_publicly_accessible_fixer import ( - fixer, + EcrRepositoriesNotPubliclyAccessibleFixer, ) - assert not fixer("repository_name_non_existing", AWS_REGION_EU_WEST_1) + assert not EcrRepositoriesNotPubliclyAccessibleFixer().fix( + resource_id="repository_name_non_existing", region=AWS_REGION_EU_WEST_1 + ) diff --git a/tests/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer_test.py b/tests/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer_test.py index 3bd5b277da..337a050903 100644 --- a/tests/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer_test.py +++ b/tests/providers/aws/services/glacier/glacier_vaults_policy_public_access/glacier_vaults_policy_public_access_fixer_test.py @@ -33,7 +33,7 @@ def mock_make_api_call_public_vault_error(self, operation_name, kwarg): return mock_make_api_call(self, operation_name, kwarg) -class Test_glacier_vaults_policy_public_access_fixer: +class TestGlacierVaultsPolicyPublicAccessFixer: @mock_aws def test_glacier_vault_public(self): with mock.patch( @@ -55,10 +55,12 @@ class Test_glacier_vaults_policy_public_access_fixer: ), ): from prowler.providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access_fixer import ( - fixer, + GlacierVaultsPolicyPublicAccessFixer, ) - assert fixer(resource_id="test-vault", region=AWS_REGION_EU_WEST_1) + assert GlacierVaultsPolicyPublicAccessFixer().fix( + resource_id="test-vault", region=AWS_REGION_EU_WEST_1 + ) @mock_aws def test_glacier_vault_public_error(self): @@ -81,7 +83,9 @@ class Test_glacier_vaults_policy_public_access_fixer: ), ): from prowler.providers.aws.services.glacier.glacier_vaults_policy_public_access.glacier_vaults_policy_public_access_fixer import ( - fixer, + GlacierVaultsPolicyPublicAccessFixer, ) - assert not fixer(resource_id="test-vault", region=AWS_REGION_EU_WEST_1) + assert not GlacierVaultsPolicyPublicAccessFixer().fix( + resource_id="test-vault", region=AWS_REGION_EU_WEST_1 + ) diff --git a/tests/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer_test.py b/tests/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer_test.py index e08524d4ce..e3a59e95a5 100644 --- a/tests/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer_test.py +++ b/tests/providers/aws/services/guardduty/guardduty_is_enabled/guardduty_is_enabled_fixer_test.py @@ -39,7 +39,7 @@ def mock_make_api_call_create_detector_failure(self, operation_name, kwarg): return mock_make_api_call(self, operation_name, kwarg) -class Test_guardduty_is_enabled_fixer: +class TestGuarddutyIsEnabledFixer: @mock_aws def test_guardduty_is_enabled_fixer(self): with mock.patch( @@ -64,10 +64,10 @@ class Test_guardduty_is_enabled_fixer: ), ): from prowler.providers.aws.services.guardduty.guardduty_is_enabled.guardduty_is_enabled_fixer import ( - fixer, + GuarddutyIsEnabledFixer, ) - assert fixer(AWS_REGION_EU_WEST_1) + assert GuarddutyIsEnabledFixer().fix(region=AWS_REGION_EU_WEST_1) @mock_aws def test_guardduty_is_enabled_fixer_failure(self): @@ -93,7 +93,7 @@ class Test_guardduty_is_enabled_fixer: ), ): from prowler.providers.aws.services.guardduty.guardduty_is_enabled.guardduty_is_enabled_fixer import ( - fixer, + GuarddutyIsEnabledFixer, ) - assert not fixer(AWS_REGION_EU_WEST_1) + assert not GuarddutyIsEnabledFixer().fix(region=AWS_REGION_EU_WEST_1) diff --git a/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer_test.py index 14f4cfeec7..c4bea27e2f 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_expires_passwords_within_90_days_or_less/iam_password_policy_expires_passwords_within_90_days_or_less_fixer_test.py @@ -10,7 +10,7 @@ from tests.providers.aws.utils import ( ) -class Test_iam_password_policy_expires_passwords_within_90_days_or_less_fixer: +class TestIamPasswordPolicyExpiresPasswordsWithin90DaysOrLessFixer: @mock_aws def test_iam_password_policy_expires_passwords_within_90_days_or_less_fixer(self): from prowler.providers.aws.services.iam.iam_service import IAM @@ -40,7 +40,9 @@ class Test_iam_password_policy_expires_passwords_within_90_days_or_less_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_expires_passwords_within_90_days_or_less.iam_password_policy_expires_passwords_within_90_days_or_less_fixer import ( - fixer, + IamPasswordPolicyExpiresPasswordsWithin90DaysOrLessFixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + assert IamPasswordPolicyExpiresPasswordsWithin90DaysOrLessFixer().fix( + resource_id=AWS_ACCOUNT_NUMBER + ) diff --git a/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer_test.py index 10103edffc..f4dd2755f8 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_lowercase/iam_password_policy_lowercase_fixer_test.py @@ -10,7 +10,7 @@ from tests.providers.aws.utils import ( ) -class Test_iam_password_policy_lowercase_fixer: +class TestIamPasswordPolicyLowercaseFixer: @mock_aws def test_iam_password_policy_lowercase_fixer(self): from prowler.providers.aws.services.iam.iam_service import IAM @@ -40,7 +40,7 @@ class Test_iam_password_policy_lowercase_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_lowercase.iam_password_policy_lowercase_fixer import ( - fixer, + IamPasswordPolicyLowercaseFixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + assert IamPasswordPolicyLowercaseFixer().fix(resource_id=AWS_ACCOUNT_NUMBER) diff --git a/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer_test.py index b837d02768..d2522f4810 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_minimum_length_14/iam_password_policy_minimum_length_14_fixer_test.py @@ -10,7 +10,7 @@ from tests.providers.aws.utils import ( ) -class Test_iam_password_policy_minimum_length_14_fixer: +class TestIamPasswordPolicyMinimumLength14Fixer: @mock_aws def test_iam_password_policy_minimum_length_14_fixer(self): from prowler.providers.aws.services.iam.iam_service import IAM @@ -40,7 +40,9 @@ class Test_iam_password_policy_minimum_length_14_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_minimum_length_14.iam_password_policy_minimum_length_14_fixer import ( - fixer, + IamPasswordPolicyMinimumLength14Fixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + assert IamPasswordPolicyMinimumLength14Fixer().fix( + resource_id=AWS_ACCOUNT_NUMBER + ) diff --git a/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer_test.py index ad7cf513e4..705c2e1384 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_number/iam_password_policy_number_fixer_test.py @@ -10,7 +10,7 @@ from tests.providers.aws.utils import ( ) -class Test_iam_password_policy_number_fixer: +class TestIamPasswordPolicyNumberFixer: @mock_aws def test_iam_password_policy_number_fixer(self): from prowler.providers.aws.services.iam.iam_service import IAM @@ -40,7 +40,7 @@ class Test_iam_password_policy_number_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_number.iam_password_policy_number_fixer import ( - fixer, + IamPasswordPolicyNumberFixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + assert IamPasswordPolicyNumberFixer().fix(resource_id=AWS_ACCOUNT_NUMBER) diff --git a/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer_test.py index 0585211708..caa1990b1e 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_reuse_24/iam_password_policy_reuse_24_fixer_test.py @@ -10,7 +10,7 @@ from tests.providers.aws.utils import ( ) -class Test_iam_password_policy_reuse_24_fixer: +class TestIamPasswordPolicyReuse24Fixer: @mock_aws def test_iam_password_policy_reuse_24_fixer(self): from prowler.providers.aws.services.iam.iam_service import IAM @@ -40,7 +40,7 @@ class Test_iam_password_policy_reuse_24_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_reuse_24.iam_password_policy_reuse_24_fixer import ( - fixer, + IamPasswordPolicyReuse24Fixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + assert IamPasswordPolicyReuse24Fixer().fix(resource_id=AWS_ACCOUNT_NUMBER) diff --git a/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer_test.py index b3ad1bebda..b71ba310be 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_symbol/iam_password_policy_symbol_fixer_test.py @@ -40,7 +40,8 @@ class Test_iam_password_policy_symbol_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_symbol.iam_password_policy_symbol_fixer import ( - fixer, + IamPasswordPolicySymbolFixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + fixer = IamPasswordPolicySymbolFixer() + assert fixer.fix(resource_id=AWS_ACCOUNT_NUMBER) diff --git a/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer_test.py b/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer_test.py index 8e37edc93c..2dc2d0a270 100644 --- a/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer_test.py +++ b/tests/providers/aws/services/iam/iam_password_policy_uppercase/iam_password_policy_uppercase_fixer_test.py @@ -40,7 +40,8 @@ class Test_iam_password_policy_uppercase_fixer: hard_expiry=True, ) from prowler.providers.aws.services.iam.iam_password_policy_uppercase.iam_password_policy_uppercase_fixer import ( - fixer, + IamPasswordPolicyUppercaseFixer, ) - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + fixer = IamPasswordPolicyUppercaseFixer() + assert fixer.fix(resource_id=AWS_ACCOUNT_NUMBER) diff --git a/tests/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer_test.py b/tests/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer_test.py index 9a9fe3b10f..8849eb7a02 100644 --- a/tests/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer_test.py +++ b/tests/providers/aws/services/kms/kms_cmk_rotation_enabled/kms_cmk_rotation_enabled_fixer_test.py @@ -30,7 +30,8 @@ class Test_kms_cmk_rotation_enabled_fixer: ): # Test Check from prowler.providers.aws.services.kms.kms_cmk_rotation_enabled.kms_cmk_rotation_enabled_fixer import ( - fixer, + KmsCmkRotationEnabledFixer, ) - assert fixer(resource_id=key["KeyId"], region=AWS_REGION_US_EAST_1) + fixer = KmsCmkRotationEnabledFixer() + assert fixer.fix(resource_id=key["KeyId"], region=AWS_REGION_US_EAST_1) diff --git a/tests/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer_test.py b/tests/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer_test.py index 52d98e2322..8378f92957 100644 --- a/tests/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer_test.py +++ b/tests/providers/aws/services/neptune/neptune_cluster_public_snapshot/neptune_cluster_public_snapshot_fixer_test.py @@ -61,10 +61,13 @@ class Test_neptune_cluster_public_snapshot_fixer: ), ): from prowler.providers.aws.services.neptune.neptune_cluster_public_snapshot.neptune_cluster_public_snapshot_fixer import ( - fixer, + NeptuneClusterPublicSnapshotFixer, ) - assert fixer(resource_id="test-snapshot", region=AWS_REGION_EU_WEST_1) + fixer = NeptuneClusterPublicSnapshotFixer() + assert fixer.fix( + resource_id="test-snapshot", region=AWS_REGION_EU_WEST_1 + ) @mock_aws def test_neptune_cluster_public_snapshot_fixer_error(self): @@ -87,9 +90,10 @@ class Test_neptune_cluster_public_snapshot_fixer: ), ): from prowler.providers.aws.services.neptune.neptune_cluster_public_snapshot.neptune_cluster_public_snapshot_fixer import ( - fixer, + NeptuneClusterPublicSnapshotFixer, ) - assert not fixer( + fixer = NeptuneClusterPublicSnapshotFixer() + assert not fixer.fix( resource_id="test-snapshot", region=AWS_REGION_EU_WEST_1 ) diff --git a/tests/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer_test.py b/tests/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer_test.py index b68c4729d1..77967eebb6 100644 --- a/tests/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer_test.py +++ b/tests/providers/aws/services/opensearch/opensearch_service_domains_not_publicly_accessible/opensearch_service_domains_not_publicly_accessible_fixer_test.py @@ -76,10 +76,13 @@ class Test_opensearch_service_domains_not_publicly_accessible_fixer: ), ): from prowler.providers.aws.services.opensearch.opensearch_service_domains_not_publicly_accessible.opensearch_service_domains_not_publicly_accessible_fixer import ( - fixer, + OpensearchServiceDomainsNotPubliclyAccessibleFixer, ) - assert not fixer("domain_name_non_existing", AWS_REGION_US_WEST_2) + fixer = OpensearchServiceDomainsNotPubliclyAccessibleFixer() + assert not fixer.fix( + resource_id="domain_name_non_existing", region=AWS_REGION_US_WEST_2 + ) @mock_aws def test_policy_data_not_restricted_with_principal_AWS(self): @@ -107,10 +110,11 @@ class Test_opensearch_service_domains_not_publicly_accessible_fixer: ), ): from prowler.providers.aws.services.opensearch.opensearch_service_domains_not_publicly_accessible.opensearch_service_domains_not_publicly_accessible_fixer import ( - fixer, + OpensearchServiceDomainsNotPubliclyAccessibleFixer, ) - assert fixer(domain_name, AWS_REGION_US_WEST_2) + fixer = OpensearchServiceDomainsNotPubliclyAccessibleFixer() + assert fixer.fix(resource_id=domain_name, region=AWS_REGION_US_WEST_2) @mock_aws def test_policy_data_not_restricted_with_principal_no_AWS(self): @@ -138,7 +142,8 @@ class Test_opensearch_service_domains_not_publicly_accessible_fixer: ), ): from prowler.providers.aws.services.opensearch.opensearch_service_domains_not_publicly_accessible.opensearch_service_domains_not_publicly_accessible_fixer import ( - fixer, + OpensearchServiceDomainsNotPubliclyAccessibleFixer, ) - assert fixer(domain_name, AWS_REGION_US_WEST_2) + fixer = OpensearchServiceDomainsNotPubliclyAccessibleFixer() + assert fixer.fix(resource_id=domain_name, region=AWS_REGION_US_WEST_2) diff --git a/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py b/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py index 5577a5623b..baad7f5666 100644 --- a/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py +++ b/tests/providers/aws/services/rds/rds_instance_no_public_access/rds_instance_no_public_access_fixer_test.py @@ -32,10 +32,13 @@ class Test_rds_instance_no_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer import ( - fixer, + RdsInstanceNoPublicAccessFixer, ) - assert fixer("db-primary-1", AWS_REGION_US_EAST_1) + fixer = RdsInstanceNoPublicAccessFixer() + assert fixer.fix( + resource_id="db-primary-1", region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_rds_public(self): @@ -64,10 +67,13 @@ class Test_rds_instance_no_public_access_fixer: # Test Fixer from prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer import ( - fixer, + RdsInstanceNoPublicAccessFixer, ) - assert fixer("db-primary-1", AWS_REGION_US_EAST_1) + fixer = RdsInstanceNoPublicAccessFixer() + assert fixer.fix( + resource_id="db-primary-1", region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_rds_cluster_public_snapshot_error(self): @@ -96,7 +102,10 @@ class Test_rds_instance_no_public_access_fixer: # Test Fixer from prowler.providers.aws.services.rds.rds_instance_no_public_access.rds_instance_no_public_access_fixer import ( - fixer, + RdsInstanceNoPublicAccessFixer, ) - assert not fixer("db-primary-2", AWS_REGION_US_EAST_1) + fixer = RdsInstanceNoPublicAccessFixer() + assert not fixer.fix( + resource_id="db-primary-2", region=AWS_REGION_US_EAST_1 + ) diff --git a/tests/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer_test.py b/tests/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer_test.py index e45d11958d..57a7e21bd7 100644 --- a/tests/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer_test.py +++ b/tests/providers/aws/services/rds/rds_snapshots_public_access/rds_snapshots_public_access_fixer_test.py @@ -36,10 +36,11 @@ class Test_rds_snapshots_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.rds.rds_snapshots_public_access.rds_snapshots_public_access_fixer import ( - fixer, + RdsSnapshotsPublicAccessFixer, ) - assert fixer("snapshot-1", AWS_REGION_US_EAST_1) + fixer = RdsSnapshotsPublicAccessFixer() + assert fixer.fix(resource_id="snapshot-1", region=AWS_REGION_US_EAST_1) @mock_aws def test_rds_public_snapshot(self): @@ -73,10 +74,11 @@ class Test_rds_snapshots_public_access_fixer: # Test Fixer from prowler.providers.aws.services.rds.rds_snapshots_public_access.rds_snapshots_public_access_fixer import ( - fixer, + RdsSnapshotsPublicAccessFixer, ) - assert fixer("snapshot-1", AWS_REGION_US_EAST_1) + fixer = RdsSnapshotsPublicAccessFixer() + assert fixer.fix(resource_id="snapshot-1", region=AWS_REGION_US_EAST_1) @mock_aws def test_rds_cluster_private_snapshot(self): @@ -107,10 +109,11 @@ class Test_rds_snapshots_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.rds.rds_snapshots_public_access.rds_snapshots_public_access_fixer import ( - fixer, + RdsSnapshotsPublicAccessFixer, ) - assert fixer("snapshot-1", AWS_REGION_US_EAST_1) + fixer = RdsSnapshotsPublicAccessFixer() + assert fixer.fix(resource_id="snapshot-1", region=AWS_REGION_US_EAST_1) @mock_aws def test_rds_cluster_public_snapshot(self): @@ -144,10 +147,11 @@ class Test_rds_snapshots_public_access_fixer: # Test Fixer from prowler.providers.aws.services.rds.rds_snapshots_public_access.rds_snapshots_public_access_fixer import ( - fixer, + RdsSnapshotsPublicAccessFixer, ) - assert fixer("snapshot-1", AWS_REGION_US_EAST_1) + fixer = RdsSnapshotsPublicAccessFixer() + assert fixer.fix(resource_id="snapshot-1", region=AWS_REGION_US_EAST_1) @mock_aws def test_rds_cluster_public_snapshot_error(self): @@ -181,7 +185,10 @@ class Test_rds_snapshots_public_access_fixer: # Test Fixer from prowler.providers.aws.services.rds.rds_snapshots_public_access.rds_snapshots_public_access_fixer import ( - fixer, + RdsSnapshotsPublicAccessFixer, ) - assert not fixer("snapshot-2", AWS_REGION_US_EAST_1) + fixer = RdsSnapshotsPublicAccessFixer() + assert not fixer.fix( + resource_id="snapshot-2", region=AWS_REGION_US_EAST_1 + ) diff --git a/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer_test.py b/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer_test.py index 3640a8b842..9c0410f901 100644 --- a/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer_test.py +++ b/tests/providers/aws/services/s3/s3_account_level_public_access_blocks/s3_account_level_public_access_blocks_fixer_test.py @@ -27,8 +27,9 @@ class Test_s3_account_level_public_access_block_fixer: ), ): from prowler.providers.aws.services.s3.s3_account_level_public_access_blocks.s3_account_level_public_access_blocks_fixer import ( - fixer, + S3AccountLevelPublicAccessBlocksFixer, ) + fixer = S3AccountLevelPublicAccessBlocksFixer() # By default, the account has not public access blocked - assert fixer(resource_id=AWS_ACCOUNT_NUMBER) + assert fixer.fix(resource_id=AWS_ACCOUNT_NUMBER) diff --git a/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer_test.py b/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer_test.py index 6d92c2261c..e30ba5e2a3 100644 --- a/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_policy_public_write_access/s3_bucket_policy_public_write_access_fixer_test.py @@ -36,10 +36,11 @@ class Test_s3_bucket_policy_public_write_access_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_policy_public_write_access.s3_bucket_policy_public_write_access_fixer import ( - fixer, + S3BucketPolicyPublicWriteAccessFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPolicyPublicWriteAccessFixer() + assert fixer.fix(resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1) @mock_aws def test_bucket_public_write_policy_error(self): @@ -70,7 +71,10 @@ class Test_s3_bucket_policy_public_write_access_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_policy_public_write_access.s3_bucket_policy_public_write_access_fixer import ( - fixer, + S3BucketPolicyPublicWriteAccessFixer, ) - assert not fixer("bucket_name_non_existing", AWS_REGION_US_EAST_1) + fixer = S3BucketPolicyPublicWriteAccessFixer() + assert not fixer.fix( + resource_id="bucket_name_non_existing", region=AWS_REGION_US_EAST_1 + ) diff --git a/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer_test.py b/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer_test.py index 39099ac39b..49e9fa2d3f 100644 --- a/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_public_access/s3_bucket_public_access_fixer_test.py @@ -27,10 +27,13 @@ class Test_s3_bucket_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_access.s3_bucket_public_access_fixer import ( - fixer, + S3BucketPublicAccessFixer, ) - assert not fixer("bucket_test_us", AWS_REGION_US_EAST_1) + fixer = S3BucketPublicAccessFixer() + assert not fixer.fix( + resource_id="bucket_test_us", region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_ACL(self): @@ -76,10 +79,13 @@ class Test_s3_bucket_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_access.s3_bucket_public_access_fixer import ( - fixer, + S3BucketPublicAccessFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicAccessFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_policy(self): @@ -125,10 +131,13 @@ class Test_s3_bucket_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_access.s3_bucket_public_access_fixer import ( - fixer, + S3BucketPublicAccessFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicAccessFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_due_to_policy_conditions_from_public_ip(self): @@ -163,7 +172,10 @@ class Test_s3_bucket_public_access_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_access.s3_bucket_public_access_fixer import ( - fixer, + S3BucketPublicAccessFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicAccessFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) diff --git a/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer_test.py b/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer_test.py index 6f7a8f2414..3ed3409a9f 100644 --- a/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_public_list_acl/s3_bucket_public_list_acl_fixer_test.py @@ -66,10 +66,13 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_list_ACL_AllUsers_READ_ACP(self): @@ -126,10 +129,13 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_list_ACL_AllUsers_FULL_CONTROL(self): @@ -186,10 +192,13 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_list_ACL_AuthenticatedUsers_READ(self): @@ -246,10 +255,13 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_list_ACL_AuthenticatedUsers_READ_ACP(self): @@ -306,10 +318,13 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_list_ACL_AuthenticatedUsers_FULL_CONTROL(self): @@ -366,10 +381,13 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_list_ACL_AllUsers_READ_error(self): @@ -426,7 +444,11 @@ class Test_s3_bucket_public_list_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_list_acl.s3_bucket_public_list_acl_fixer import ( - fixer, + S3BucketPublicListAclFixer, ) - assert not fixer("bucket_name_us_non_existing", AWS_REGION_US_EAST_1) + fixer = S3BucketPublicListAclFixer() + assert not fixer.fix( + resource_id="bucket_name_us_non_existing", + region=AWS_REGION_US_EAST_1, + ) diff --git a/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer_test.py b/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer_test.py index 768ad12f79..b231c85775 100644 --- a/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer_test.py +++ b/tests/providers/aws/services/s3/s3_bucket_public_write_acl/s3_bucket_public_write_acl_fixer_test.py @@ -66,10 +66,13 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_write_ACL_AllUsers_WRITE_ACP(self): @@ -126,10 +129,13 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_write_ACL_AllUsers_FULL_CONTROL(self): @@ -186,10 +192,13 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_write_ACL_AuthenticatedUsers_WRITE(self): @@ -246,10 +255,13 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_write_ACL_AuthenticatedUsers_WRITE_ACP(self): @@ -306,10 +318,13 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_write_ACL_AuthenticatedUsers_FULL_CONTROL(self): @@ -366,10 +381,13 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert fixer(bucket_name_us, AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert fixer.fix( + resource_id=bucket_name_us, region=AWS_REGION_US_EAST_1 + ) @mock_aws def test_bucket_public_write_ACL_AllUsers_WRITE_error(self): @@ -426,7 +444,11 @@ class Test_s3_bucket_public_write_acl_fixer: ): # Test Fixer from prowler.providers.aws.services.s3.s3_bucket_public_write_acl.s3_bucket_public_write_acl_fixer import ( - fixer, + S3BucketPublicWriteAclFixer, ) - assert not fixer("bucket_name_us_non_existing", AWS_REGION_US_EAST_1) + fixer = S3BucketPublicWriteAclFixer() + assert not fixer.fix( + resource_id="bucket_name_us_non_existing", + region=AWS_REGION_US_EAST_1, + ) diff --git a/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer_test.py b/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer_test.py index 1d135bda85..a5b11478a8 100644 --- a/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer_test.py +++ b/tests/providers/aws/services/securityhub/securityhub_enabled/securityhub_enabled_fixer_test.py @@ -8,7 +8,7 @@ from prowler.providers.aws.services.securityhub.securityhub_service import ( from tests.providers.aws.utils import AWS_REGION_EU_WEST_1 -class test_securityhub_enabled_fixer: +class TestSecurityhubEnabledFixer: @mock_aws def test_securityhub_enabled_fixer(self): securityhub_client = mock.MagicMock @@ -28,7 +28,8 @@ class test_securityhub_enabled_fixer: ): # Test Check from prowler.providers.aws.services.securityhub.securityhub_enabled.securityhub_enabled_fixer import ( - fixer, + SecurityhubEnabledFixer, ) - assert fixer(AWS_REGION_EU_WEST_1) + fixer = SecurityhubEnabledFixer() + assert fixer.fix(region=AWS_REGION_EU_WEST_1) diff --git a/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer_test.py b/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer_test.py index dfef1e6952..2dc7abe25d 100644 --- a/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer_test.py +++ b/tests/providers/aws/services/sqs/sqs_queues_not_publicly_accessible/sqs_queues_not_publicly_accessible_fixer_test.py @@ -7,7 +7,7 @@ from moto import mock_aws from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider -class Test_sqs_queues_not_publicly_accessible_fixer: +class TestSqsQueuesNotPubliclyAccessibleFixer: @mock_aws def test_queue_public(self): sqs_client = client("sqs", region_name=AWS_REGION_EU_WEST_1) @@ -37,10 +37,11 @@ class Test_sqs_queues_not_publicly_accessible_fixer: ): # Test Fixer from prowler.providers.aws.services.sqs.sqs_queues_not_publicly_accessible.sqs_queues_not_publicly_accessible_fixer import ( - fixer, + SqsQueuesNotPubliclyAccessibleFixer, ) - assert fixer(queue_url, AWS_REGION_EU_WEST_1) + fixer = SqsQueuesNotPubliclyAccessibleFixer() + assert fixer.fix(resource_id=queue_url, region=AWS_REGION_EU_WEST_1) @mock_aws def test_queue_public_with_aws(self): @@ -73,10 +74,11 @@ class Test_sqs_queues_not_publicly_accessible_fixer: ): # Test Fixer from prowler.providers.aws.services.sqs.sqs_queues_not_publicly_accessible.sqs_queues_not_publicly_accessible_fixer import ( - fixer, + SqsQueuesNotPubliclyAccessibleFixer, ) - assert fixer(queue_url, AWS_REGION_EU_WEST_1) + fixer = SqsQueuesNotPubliclyAccessibleFixer() + assert fixer.fix(resource_id=queue_url, region=AWS_REGION_EU_WEST_1) @mock_aws def test_queue_public_error(self): @@ -109,7 +111,10 @@ class Test_sqs_queues_not_publicly_accessible_fixer: ): # Test Fixer from prowler.providers.aws.services.sqs.sqs_queues_not_publicly_accessible.sqs_queues_not_publicly_accessible_fixer import ( - fixer, + SqsQueuesNotPubliclyAccessibleFixer, ) - assert not fixer("queue_url_non_existing", AWS_REGION_EU_WEST_1) + fixer = SqsQueuesNotPubliclyAccessibleFixer() + assert not fixer.fix( + resource_id="queue_url_non_existing", region=AWS_REGION_EU_WEST_1 + )