mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-21 02:44:16 +00:00
chore(aws): change fixers structure
This commit is contained in:
1 parent
4fcb6b34e7
commit
761c97100a
45 files changed
+1562
-899
No files matched your search
+2
-2
@@ -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",
|
||||
|
||||
+54
-30
@@ -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
|
||||
+54
-30
@@ -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
|
||||
+53
-26
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+64
-38
@@ -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
|
||||
+55
-27
@@ -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
|
||||
+59
-33
@@ -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
|
||||
+56
-32
@@ -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
|
||||
+59
-33
@@ -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
|
||||
+79
-53
@@ -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
|
||||
+59
-33
@@ -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
|
||||
+54
-30
@@ -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
|
||||
+62
-38
@@ -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
|
||||
+55
-33
@@ -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
|
||||
+55
-29
@@ -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
|
||||
+57
-30
@@ -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
|
||||
+76
-55
@@ -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
|
||||
+13
-10
@@ -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
|
||||
)
|
||||
+9
-5
@@ -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
|
||||
)
|
||||
+5
-5
@@ -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)
|
||||
+5
-3
@@ -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
|
||||
)
|
||||
+3
-3
@@ -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)
|
||||
+5
-3
@@ -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
|
||||
)
|
||||
+3
-3
@@ -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)
|
||||
+3
-3
@@ -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)
|
||||
+3
-2
@@ -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)
|
||||
+3
-2
@@ -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)
|
||||
+3
-2
@@ -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)
|
||||
+8
-4
@@ -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
|
||||
)
|
||||
+11
-6
@@ -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)
|
||||
+15
-6
@@ -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
|
||||
)
|
||||
+17
-10
@@ -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
|
||||
)
|
||||
+3
-2
@@ -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)
|
||||
+8
-4
@@ -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
|
||||
)
|
||||
+20
-8
@@ -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
|
||||
)
|
||||
+36
-14
@@ -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,
|
||||
)
|
||||
+36
-14
@@ -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,
|
||||
)
|
||||
+4
-3
@@ -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)
|
||||
+12
-7
@@ -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
|
||||
)
|
||||
Reference in new issue
Block a user