mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
fix(iam): check always if root credentials are present (#8013)
Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com>
This commit is contained in:
+1
-1
@@ -23,7 +23,7 @@
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Use the credential report to check the user and ensure the access_key_1_active and access_key_2_active fields are set to FALSE.",
|
||||
"Text": "Use the credential report to check the user and ensure the access_key_1_active and access_key_2_active fields are set to FALSE. If using AWS Organizations, consider enabling Centralized Root Management and removing individual root credentials.",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_getting-report.html"
|
||||
}
|
||||
},
|
||||
|
||||
+55
-29
@@ -5,39 +5,65 @@ from prowler.providers.aws.services.iam.iam_client import iam_client
|
||||
class iam_no_root_access_key(Check):
|
||||
def execute(self) -> Check_Report_AWS:
|
||||
findings = []
|
||||
# Check if the root credentials are managed by AWS Organizations
|
||||
if (
|
||||
iam_client.organization_features is not None
|
||||
and "RootCredentialsManagement" not in iam_client.organization_features
|
||||
):
|
||||
|
||||
if iam_client.credential_report:
|
||||
for user in iam_client.credential_report:
|
||||
if user["user"] == "<root_account>":
|
||||
report = Check_Report_AWS(metadata=self.metadata(), resource=user)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = user["user"]
|
||||
report.resource_arn = user["arn"]
|
||||
if (
|
||||
user["access_key_1_active"] == "false"
|
||||
and user["access_key_2_active"] == "false"
|
||||
):
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"Root account does not have access keys."
|
||||
password_enabled = user["password_enabled"] == "true"
|
||||
access_key_1_active = user["access_key_1_active"] == "true"
|
||||
access_key_2_active = user["access_key_2_active"] == "true"
|
||||
|
||||
# Only report if root actually has credentials
|
||||
if password_enabled or access_key_1_active or access_key_2_active:
|
||||
report = Check_Report_AWS(
|
||||
metadata=self.metadata(), resource=user
|
||||
)
|
||||
elif (
|
||||
user["access_key_1_active"] == "true"
|
||||
and user["access_key_2_active"] == "true"
|
||||
):
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"Root account has two active access keys."
|
||||
report.region = iam_client.region
|
||||
report.resource_id = user["user"]
|
||||
report.resource_arn = user["arn"]
|
||||
|
||||
# Check if organization manages root credentials
|
||||
org_managed = (
|
||||
iam_client.organization_features is not None
|
||||
and "RootCredentialsManagement"
|
||||
in iam_client.organization_features
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"Root account has one active access key."
|
||||
)
|
||||
findings.append(report)
|
||||
|
||||
if not access_key_1_active and not access_key_2_active:
|
||||
report.status = "PASS"
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has password configured but no access keys. "
|
||||
"Consider removing individual root credentials since organizational "
|
||||
"root management is active."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
"Root account does not have access keys."
|
||||
)
|
||||
elif access_key_1_active and access_key_2_active:
|
||||
report.status = "FAIL"
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has two active access keys "
|
||||
"despite organizational root management being enabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
"Root account has two active access keys."
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has one active access key "
|
||||
"despite organizational root management being enabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
"Root account has one active access key."
|
||||
)
|
||||
findings.append(report)
|
||||
break
|
||||
|
||||
return findings
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Using IAM console navigate to Dashboard and expand Activate MFA on your root account.",
|
||||
"Text": "Using IAM console navigate to Dashboard and expand Activate MFA on your root account. If using AWS Organizations, consider enabling Centralized Root Management and removing individual root credentials.",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa"
|
||||
}
|
||||
},
|
||||
|
||||
+69
-32
@@ -7,40 +7,77 @@ class iam_root_hardware_mfa_enabled(Check):
|
||||
findings = []
|
||||
# This check is only available in Commercial Partition
|
||||
if iam_client.audited_partition == "aws":
|
||||
# Check if the root credentials are managed by AWS Organizations
|
||||
if (
|
||||
iam_client.organization_features is not None
|
||||
and "RootCredentialsManagement" not in iam_client.organization_features
|
||||
):
|
||||
if iam_client.account_summary:
|
||||
virtual_mfa = False
|
||||
report = Check_Report_AWS(
|
||||
metadata=self.metadata(),
|
||||
resource=iam_client.account_summary,
|
||||
)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = "<root_account>"
|
||||
report.resource_arn = iam_client.mfa_arn_template
|
||||
if iam_client.credential_report:
|
||||
for user in iam_client.credential_report:
|
||||
if user["user"] == "<root_account>":
|
||||
password_enabled = user["password_enabled"] == "true"
|
||||
access_key_1_active = user["access_key_1_active"] == "true"
|
||||
access_key_2_active = user["access_key_2_active"] == "true"
|
||||
|
||||
if (
|
||||
iam_client.account_summary["SummaryMap"]["AccountMFAEnabled"]
|
||||
> 0
|
||||
):
|
||||
for mfa in iam_client.virtual_mfa_devices:
|
||||
# If the ARN of the associated IAM user of the Virtual MFA device is "arn:aws:iam::[aws-account-id]:root", your AWS root account is not using a hardware-based MFA device for MFA protection.
|
||||
if "root" in mfa.get("User", {}).get("Arn", ""):
|
||||
virtual_mfa = True
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Root account has a virtual MFA instead of a hardware MFA device enabled."
|
||||
if not virtual_mfa:
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"Root account has a hardware MFA device enabled."
|
||||
# Only report if root actually has credentials
|
||||
if (
|
||||
password_enabled
|
||||
or access_key_1_active
|
||||
or access_key_2_active
|
||||
) and iam_client.account_summary:
|
||||
virtual_mfa = False
|
||||
report = Check_Report_AWS(
|
||||
metadata=self.metadata(),
|
||||
resource=user,
|
||||
)
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "MFA is not enabled for root account."
|
||||
report.region = iam_client.region
|
||||
report.resource_id = user["user"]
|
||||
report.resource_arn = iam_client.mfa_arn_template
|
||||
|
||||
findings.append(report)
|
||||
# Check if organization manages root credentials
|
||||
org_managed = (
|
||||
iam_client.organization_features is not None
|
||||
and "RootCredentialsManagement"
|
||||
in iam_client.organization_features
|
||||
)
|
||||
|
||||
if (
|
||||
iam_client.account_summary["SummaryMap"][
|
||||
"AccountMFAEnabled"
|
||||
]
|
||||
> 0
|
||||
):
|
||||
for mfa in iam_client.virtual_mfa_devices:
|
||||
# If the ARN of the associated IAM user of the Virtual MFA device is "arn:aws:iam::[aws-account-id]:root", your AWS root account is not using a hardware-based MFA device for MFA protection.
|
||||
if "root" in mfa.get("User", {}).get("Arn", ""):
|
||||
virtual_mfa = True
|
||||
report.status = "FAIL"
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has credentials with virtual MFA "
|
||||
"instead of hardware MFA despite organizational root management being enabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = "Root account has a virtual MFA instead of a hardware MFA device enabled."
|
||||
break
|
||||
|
||||
if not virtual_mfa:
|
||||
report.status = "PASS"
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has credentials with hardware MFA enabled. "
|
||||
"Consider removing individual root credentials since organizational "
|
||||
"root management is active."
|
||||
)
|
||||
else:
|
||||
report.status_extended = "Root account has a hardware MFA device enabled."
|
||||
else:
|
||||
report.status = "FAIL"
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has credentials without MFA "
|
||||
"despite organizational root management being enabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
"MFA is not enabled for root account."
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Using IAM console navigate to Dashboard and expand Activate MFA on your root account.",
|
||||
"Text": "Using IAM console navigate to Dashboard and expand Activate MFA on your root account. If using AWS Organizations, consider enabling Centralized Root Management and removing individual root credentials.",
|
||||
"Url": "https://docs.aws.amazon.com/IAM/latest/UserGuide/id_root-user.html#id_root-user_manage_mfa"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -5,28 +5,53 @@ from prowler.providers.aws.services.iam.iam_client import iam_client
|
||||
class iam_root_mfa_enabled(Check):
|
||||
def execute(self) -> Check_Report_AWS:
|
||||
findings = []
|
||||
# Check if the root credentials are managed by AWS Organizations
|
||||
if (
|
||||
iam_client.organization_features is not None
|
||||
and "RootCredentialsManagement" not in iam_client.organization_features
|
||||
):
|
||||
if iam_client.credential_report:
|
||||
for user in iam_client.credential_report:
|
||||
if user["user"] == "<root_account>":
|
||||
|
||||
if iam_client.credential_report:
|
||||
for user in iam_client.credential_report:
|
||||
if user["user"] == "<root_account>":
|
||||
password_enabled = user["password_enabled"] == "true"
|
||||
access_key_1_active = user["access_key_1_active"] == "true"
|
||||
access_key_2_active = user["access_key_2_active"] == "true"
|
||||
|
||||
# Only report if root actually has credentials
|
||||
if password_enabled or access_key_1_active or access_key_2_active:
|
||||
report = Check_Report_AWS(
|
||||
metadata=self.metadata(), resource=user
|
||||
)
|
||||
report.region = iam_client.region
|
||||
report.resource_id = user["user"]
|
||||
report.resource_arn = user["arn"]
|
||||
|
||||
# Check if organization manages root credentials
|
||||
org_managed = (
|
||||
iam_client.organization_features is not None
|
||||
and "RootCredentialsManagement"
|
||||
in iam_client.organization_features
|
||||
)
|
||||
|
||||
if user["mfa_active"] == "false":
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"MFA is not enabled for root account."
|
||||
)
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has credentials without MFA "
|
||||
"despite organizational root management being enabled."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
"MFA is not enabled for root account."
|
||||
)
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = "MFA is enabled for root account."
|
||||
if org_managed:
|
||||
report.status_extended = (
|
||||
"Root account has credentials with MFA enabled. "
|
||||
"Consider removing individual root credentials since organizational "
|
||||
"root management is active."
|
||||
)
|
||||
else:
|
||||
report.status_extended = (
|
||||
"MFA is enabled for root account."
|
||||
)
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
|
||||
@@ -54,7 +54,7 @@ class IAM(AWSService):
|
||||
self.role_arn_template = f"arn:{self.audited_partition}:iam:{self.region}:{self.audited_account}:role"
|
||||
self.password_policy_arn_template = f"arn:{self.audited_partition}:iam:{self.region}:{self.audited_account}:password-policy"
|
||||
self.mfa_arn_template = (
|
||||
f"arn:{self.audited_partition}:iam:{self.region}:{self.audited_account}:mfa"
|
||||
f"arn:{self.audited_partition}:iam::{self.audited_account}:mfa"
|
||||
)
|
||||
self.users = self._get_users()
|
||||
self.roles = self._get_roles()
|
||||
|
||||
+184
@@ -33,11 +33,13 @@ class Test_iam_no_root_access_key_test:
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
@@ -75,11 +77,13 @@ class Test_iam_no_root_access_key_test:
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
@@ -117,11 +121,13 @@ class Test_iam_no_root_access_key_test:
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "false"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
@@ -159,11 +165,13 @@ class Test_iam_no_root_access_key_test:
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "false"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
@@ -174,3 +182,179 @@ class Test_iam_no_root_access_key_test:
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
def test_root_no_credentials(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "false"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
# Should return no findings since root has no credentials
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_root_no_access_keys_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Root account has password configured but no access keys. Consider removing individual root credentials since organizational root management is active."
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
def test_root_access_keys_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Root account has one active access key despite organizational root management being enabled."
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
def test_root_both_access_keys_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
):
|
||||
with mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client:
|
||||
from prowler.providers.aws.services.iam.iam_no_root_access_key.iam_no_root_access_key import (
|
||||
iam_no_root_access_key,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:user/<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "false"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
check = iam_no_root_access_key()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Root account has two active access keys despite organizational root management being enabled."
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== "arn:aws:iam::123456789012:user/<root_account>"
|
||||
)
|
||||
|
||||
+267
-36
@@ -1,5 +1,9 @@
|
||||
from re import search
|
||||
from unittest import mock
|
||||
|
||||
from boto3 import client
|
||||
from moto import mock_aws
|
||||
|
||||
from tests.providers.aws.utils import (
|
||||
AWS_ACCOUNT_NUMBER,
|
||||
AWS_REGION_US_EAST_1,
|
||||
@@ -15,23 +19,14 @@ class Test_iam_root_hardware_mfa_enabled_test:
|
||||
set_mocked_aws_provider,
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
def test_root_virtual_mfa_enabled(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
iam_client.virtual_mfa_devices = [
|
||||
{
|
||||
"SerialNumber": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa/mfa",
|
||||
"User": {"Arn": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"},
|
||||
}
|
||||
]
|
||||
iam_client.audited_partition = "aws"
|
||||
iam_client.region = AWS_REGION_US_EAST_1
|
||||
iam_client.mfa_arn_template = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
iam_client.organization_features = []
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -40,13 +35,32 @@ class Test_iam_root_hardware_mfa_enabled_test:
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=iam_client,
|
||||
),
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
# Set up virtual MFA device for root
|
||||
service_client.virtual_mfa_devices = [
|
||||
{
|
||||
"SerialNumber": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa/mfa",
|
||||
"User": {"Arn": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"},
|
||||
}
|
||||
]
|
||||
service_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
@@ -58,18 +72,14 @@ class Test_iam_root_hardware_mfa_enabled_test:
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
|
||||
@mock_aws
|
||||
def test_root_hardware_mfa_enabled(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
iam_client.virtual_mfa_devices = []
|
||||
iam_client.audited_partition = "aws"
|
||||
iam_client.region = AWS_REGION_US_EAST_1
|
||||
iam_client.mfa_arn_template = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
iam_client.organization_features = []
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -78,13 +88,27 @@ class Test_iam_root_hardware_mfa_enabled_test:
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=iam_client,
|
||||
),
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
# No virtual MFA devices (indicating hardware MFA)
|
||||
service_client.virtual_mfa_devices = []
|
||||
service_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
@@ -96,16 +120,14 @@ class Test_iam_root_hardware_mfa_enabled_test:
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
|
||||
@mock_aws
|
||||
def test_root_hardware_mfa_enabled_none_summary(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.account_summary = None
|
||||
iam_client.virtual_mfa_devices = []
|
||||
iam_client.audited_partition = "aws"
|
||||
iam_client.region = AWS_REGION_US_EAST_1
|
||||
iam_client.mfa_arn_template = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
iam_client.organization_features = []
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
@@ -114,13 +136,222 @@ class Test_iam_root_hardware_mfa_enabled_test:
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=iam_client,
|
||||
),
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
# No account summary
|
||||
service_client.account_summary = None
|
||||
service_client.virtual_mfa_devices = []
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_root_no_credentials(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
service_client.virtual_mfa_devices = []
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "false"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
# Should return no findings since root has no credentials
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_root_hardware_mfa_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
service_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
service_client.virtual_mfa_devices = []
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"Root account has credentials with hardware MFA enabled. "
|
||||
"Consider removing individual root credentials since organizational "
|
||||
"root management is active.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
|
||||
@mock_aws
|
||||
def test_root_virtual_mfa_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
service_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 1},
|
||||
}
|
||||
service_client.virtual_mfa_devices = [
|
||||
{
|
||||
"SerialNumber": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa/mfa",
|
||||
"User": {"Arn": f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"},
|
||||
}
|
||||
]
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root account has credentials with virtual MFA instead of hardware MFA "
|
||||
"despite organizational root management being enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
|
||||
@mock_aws
|
||||
def test_root_no_mfa_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_hardware_mfa_enabled.iam_root_hardware_mfa_enabled import (
|
||||
iam_root_hardware_mfa_enabled,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
service_client.account_summary = {
|
||||
"SummaryMap": {"AccountMFAEnabled": 0},
|
||||
}
|
||||
service_client.virtual_mfa_devices = []
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root"
|
||||
|
||||
check = iam_root_hardware_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root account has credentials without MFA "
|
||||
"despite organizational root management being enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:mfa"
|
||||
|
||||
@@ -42,12 +42,16 @@ class Test_iam_root_mfa_enabled_test:
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "false"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"MFA is not enabled for root account.", result[0].status_extended
|
||||
@@ -80,13 +84,149 @@ class Test_iam_root_mfa_enabled_test:
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "true"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search("MFA is enabled for root account.", result[0].status_extended)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == service_client.credential_report[0]["arn"]
|
||||
|
||||
@mock_aws
|
||||
def test_root_no_credentials(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled import (
|
||||
iam_root_mfa_enabled,
|
||||
)
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "false"
|
||||
service_client.credential_report[0]["password_enabled"] = "false"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
# Should return no findings since root has no credentials
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_root_mfa_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled import (
|
||||
iam_root_mfa_enabled,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "true"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "true"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "false"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert search(
|
||||
"Root account has credentials with MFA enabled. "
|
||||
"Consider removing individual root credentials since organizational "
|
||||
"root management is active.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == service_client.credential_report[0]["arn"]
|
||||
|
||||
@mock_aws
|
||||
def test_root_mfa_disabled_with_organizational_management_enabled(self):
|
||||
iam_client = client("iam")
|
||||
user = "test-user"
|
||||
iam_client.create_user(UserName=user)["User"]["Arn"]
|
||||
|
||||
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
|
||||
from prowler.providers.aws.services.iam.iam_service import IAM
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=aws_provider,
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled.iam_client",
|
||||
new=IAM(aws_provider),
|
||||
) as service_client,
|
||||
):
|
||||
from prowler.providers.aws.services.iam.iam_root_mfa_enabled.iam_root_mfa_enabled import (
|
||||
iam_root_mfa_enabled,
|
||||
)
|
||||
|
||||
# Set up organizational root management
|
||||
service_client.organization_features = ["RootCredentialsManagement"]
|
||||
|
||||
service_client.credential_report[0]["user"] = "<root_account>"
|
||||
service_client.credential_report[0]["mfa_active"] = "false"
|
||||
service_client.credential_report[0]["password_enabled"] = "true"
|
||||
service_client.credential_report[0]["access_key_1_active"] = "false"
|
||||
service_client.credential_report[0]["access_key_2_active"] = "true"
|
||||
service_client.credential_report[0][
|
||||
"arn"
|
||||
] = "arn:aws:iam::123456789012:<root_account>:root"
|
||||
|
||||
check = iam_root_mfa_enabled()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert search(
|
||||
"Root account has credentials without MFA "
|
||||
"despite organizational root management being enabled.",
|
||||
result[0].status_extended,
|
||||
)
|
||||
assert result[0].resource_id == "<root_account>"
|
||||
assert result[0].resource_arn == service_client.credential_report[0]["arn"]
|
||||
|
||||
Reference in New Issue
Block a user