chore(aws): change fixers structure

This commit is contained in:
Daniel Barranquero committed 2025-06-12 12:35:40 +02:00
1 parent 4fcb6b34e7
commit 761c97100a
45 files changed
+1562 -899

No files matched your search

@@ -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",
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
)
@@ -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
)
@@ -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)
@@ -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
)
@@ -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)
@@ -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
)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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
)
@@ -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)
@@ -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
)
@@ -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
)
@@ -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)
@@ -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
)
@@ -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
)
@@ -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,
)
@@ -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,
)
@@ -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)
@@ -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
)