mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-30 07:14:20 +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 parent
ddd3a292f8
commit
fc4536dca8
10 files changed
+756
-113
No files matched your search
+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