diff --git a/prowler/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts.py b/prowler/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts.py index d096ed3e07..ea5c74fe78 100644 --- a/prowler/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts.py +++ b/prowler/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts.py @@ -5,17 +5,23 @@ from prowler.providers.aws.services.iam.iam_client import iam_client class iam_check_saml_providers_sts(Check): def execute(self) -> Check_Report_AWS: findings = [] - if iam_client.saml_providers: - for provider in iam_client.saml_providers: - report = Check_Report_AWS(self.metadata()) - provider_name = provider["Arn"].split("/")[1] - report.resource_id = provider_name - report.resource_arn = provider["Arn"] - report.region = iam_client.region - report.status = "PASS" - report.status_extended = ( - f"SAML Provider {provider_name} has been found." - ) - findings.append(report) + if not iam_client.saml_providers and iam_client.saml_providers is not None: + report = Check_Report_AWS(self.metadata()) + report.resource_id = iam_client.audited_account + report.resource_arn = iam_client.audited_account_arn + report.region = iam_client.region + report.status = "FAIL" + report.status_extended = "No SAML Providers found." + findings.append(report) + + for provider_arn, provider in iam_client.saml_providers.items(): + report = Check_Report_AWS(self.metadata()) + report.resource_id = provider.name + report.resource_arn = provider_arn + report.resource_tags = provider.tags + report.region = iam_client.region + report.status = "PASS" + report.status_extended = f"SAML Provider {provider.name} has been found." + findings.append(report) return findings diff --git a/prowler/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored.py b/prowler/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored.py index e99210e10a..00a952f82a 100644 --- a/prowler/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored.py +++ b/prowler/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored.py @@ -13,6 +13,7 @@ class iam_no_expired_server_certificates_stored(Check): report.region = iam_client.region report.resource_id = certificate.id report.resource_arn = certificate.arn + report.resource_tags = certificate.tags expiration_days = (datetime.now(timezone.utc) - certificate.expiration).days if expiration_days >= 0: report.status = "FAIL" diff --git a/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.py b/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.py index 9637471396..512faca0b0 100644 --- a/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.py +++ b/prowler/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles.py @@ -16,6 +16,7 @@ class iam_policy_attached_only_to_group_or_roles(Check): report.status_extended = f"User {user.name} has the policy {policy['PolicyName']} attached." report.resource_id = f"{user.name}/{policy['PolicyName']}" report.resource_arn = user.arn + report.resource_tags = user.tags findings.append(report) if user.inline_policies: for policy in user.inline_policies: @@ -25,6 +26,7 @@ class iam_policy_attached_only_to_group_or_roles(Check): report.status_extended = f"User {user.name} has the inline policy {policy} attached." report.resource_id = f"{user.name}/{policy}" report.resource_arn = user.arn + report.resource_tags = user.tags findings.append(report) else: @@ -32,6 +34,7 @@ class iam_policy_attached_only_to_group_or_roles(Check): report.region = iam_client.region report.resource_id = user.name report.resource_arn = user.arn + report.resource_tags = user.tags report.status = "PASS" report.status_extended = ( f"User {user.name} has no inline or attached policies." diff --git a/prowler/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days.py b/prowler/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days.py index cc7b3bfbe7..3de61166c5 100644 --- a/prowler/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days.py +++ b/prowler/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days.py @@ -12,9 +12,15 @@ maximum_expiration_days = 90 class iam_rotate_access_key_90_days(Check): def execute(self) -> Check_Report_AWS: findings = [] - response = iam_client.credential_report - for user in response: + for user in iam_client.credential_report: + # Search user in iam_client.users to get tags + user_tags = [] + for iam_user in iam_client.users: + if iam_user.arn == user["arn"]: + user_tags = iam_user.tags + break + if ( user["access_key_1_last_rotated"] == "N/A" and user["access_key_2_last_rotated"] == "N/A" @@ -23,6 +29,7 @@ class iam_rotate_access_key_90_days(Check): report.region = iam_client.region report.resource_id = user["user"] report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "PASS" report.status_extended = ( f"User {user['user']} does not have access keys." @@ -44,6 +51,7 @@ class iam_rotate_access_key_90_days(Check): report.region = iam_client.region report.resource_id = user["user"] report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "FAIL" report.status_extended = f"User {user['user']} has not rotated access key 1 in over 90 days ({access_key_1_last_rotated.days} days)." findings.append(report) @@ -60,6 +68,7 @@ class iam_rotate_access_key_90_days(Check): report.region = iam_client.region report.resource_id = user["user"] report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "FAIL" report.status_extended = f"User {user['user']} has not rotated access key 2 in over 90 days ({access_key_2_last_rotated.days} days)." findings.append(report) @@ -69,6 +78,7 @@ class iam_rotate_access_key_90_days(Check): report.region = iam_client.region report.resource_id = user["user"] report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "PASS" report.status_extended = f"User {user['user']} does not have access keys older than 90 days." findings.append(report) diff --git a/prowler/providers/aws/services/iam/iam_service.py b/prowler/providers/aws/services/iam/iam_service.py index 565867e565..8bfcbd7ced 100644 --- a/prowler/providers/aws/services/iam/iam_service.py +++ b/prowler/providers/aws/services/iam/iam_service.py @@ -47,7 +47,6 @@ def is_service_role(role): return False -################## IAM class IAM(AWSService): def __init__(self, provider): # Call AWSService's __init__ @@ -89,13 +88,21 @@ class IAM(AWSService): self._list_inline_role_policies() self.saml_providers = self._list_saml_providers() self.server_certificates = self._list_server_certificates() - self._list_tags_for_resource() self.access_keys_metadata = {} self._get_access_keys_metadata() self.last_accessed_services = {} self._get_last_accessed_services() self.user_temporary_credentials_usage = {} self._get_user_temporary_credentials_usage() + # List missing tags + self.__threading_call__(self._list_tags, self.users) + self.__threading_call__(self._list_tags, self.roles) + self.__threading_call__( + self._list_tags, + [policy for policy in self.policies if policy.type == "Custom"], + ) + self.__threading_call__(self._list_tags, self.server_certificates) + self.__threading_call__(self._list_tags, self.saml_providers.values()) def _get_client(self): return self.client @@ -733,17 +740,31 @@ class IAM(AWSService): def _list_saml_providers(self): logger.info("IAM - List SAML Providers...") + saml_providers = {} try: - saml_providers = self.client.list_saml_providers()["SAMLProviderList"] + saml_providers_list = self.client.list_saml_providers()["SAMLProviderList"] + + for provider in saml_providers_list: + if not self.audit_resources or ( + is_resource_filtered(provider["Arn"], self.audit_resources) + ): + saml_providers[provider["Arn"]] = SAMLProvider( + name=provider["Arn"].split("/")[-1], arn=provider["Arn"] + ) + except ClientError as error: + logger.error( + f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" + ) + if error.response["Error"]["Code"] == "AccessDenied": + saml_providers = None except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - saml_providers = None - finally: - return saml_providers - def _list_server_certificates(self): + return saml_providers + + def _list_server_certificates(self) -> list: logger.info("IAM - List Server Certificates...") try: server_certificates = [] @@ -768,71 +789,30 @@ class IAM(AWSService): finally: return server_certificates - def _list_tags_for_resource(self): + def _list_tags(self, resource: any): logger.info("IAM - List Tags...") try: - if self.roles: - for role in self.roles: - try: - response = self.client.list_role_tags(RoleName=role.name)[ - "Tags" - ] - role.tags = response - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - role.tags = [] - else: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - - try: - for user in self.users: - try: - response = self.client.list_user_tags(UserName=user.name)["Tags"] - user.tags = response - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - user.tags = [] - else: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - - try: - for policy in self.policies: - try: - if policy.type != "Inline": - response = self.client.list_policy_tags(PolicyArn=policy.arn)[ - "Tags" - ] - policy.tags = response - except ClientError as error: - if error.response["Error"]["Code"] == "NoSuchEntity": - policy.tags = [] - else: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - except Exception as error: - logger.error( - f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" - ) - + if isinstance(resource, Role): + resource.tags = self.client.list_role_tags(RoleName=resource.name).get( + "Tags", [] + ) + elif isinstance(resource, User): + resource.tags = self.client.list_user_tags(UserName=resource.name).get( + "Tags", [] + ) + elif isinstance(resource, Policy): + if resource.type == "Custom": + resource.tags = self.client.list_policy_tags( + PolicyArn=resource.arn + ).get("Tags", []) + elif isinstance(resource, Certificate): + resource.tags = self.client.list_server_certificate_tags( + ServerCertificateName=resource.name + ).get("Tags", []) + elif isinstance(resource, SAMLProvider): + resource.tags = self.client.list_saml_provider_tags( + SAMLProviderArn=resource.arn + ).get("Tags", []) except Exception as error: logger.error( f"{self.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" @@ -952,7 +932,7 @@ class User(BaseModel): console_access: Optional[bool] attached_policies: list[dict] = [] inline_policies: list[str] = [] - tags: Optional[list] = [] + tags: Optional[list] class Role(BaseModel): @@ -962,7 +942,7 @@ class Role(BaseModel): is_service_role: bool attached_policies: list[dict] = [] inline_policies: list[str] = [] - tags: Optional[list] = [] + tags: Optional[list] class Group(BaseModel): @@ -991,6 +971,7 @@ class Certificate(BaseModel): id: str arn: str expiration: datetime + tags: Optional[list] class Policy(BaseModel): @@ -1002,3 +983,9 @@ class Policy(BaseModel): attached: bool document: Optional[dict] tags: Optional[list] = [] + + +class SAMLProvider(BaseModel): + name: str + arn: str + tags: Optional[list] diff --git a/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.py b/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.py index 5463585bc0..6267192d97 100644 --- a/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.py +++ b/prowler/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused.py @@ -14,6 +14,13 @@ class iam_user_accesskey_unused(Check): ) findings = [] for user in iam_client.credential_report: + # Search user in iam_client.users to get tags + user_tags = [] + for iam_user in iam_client.users: + if iam_user.arn == user["arn"]: + user_tags = iam_user.tags + break + if ( user["access_key_1_active"] != "true" and user["access_key_2_active"] != "true" @@ -22,6 +29,7 @@ class iam_user_accesskey_unused(Check): report.region = iam_client.region report.resource_id = user["user"] report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "PASS" report.status_extended = ( f"User {user['user']} does not have access keys." @@ -41,6 +49,7 @@ class iam_user_accesskey_unused(Check): report.region = iam_client.region report.resource_id = user["user"] + "/AccessKey1" report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "FAIL" report.status_extended = f"User {user['user']} has not used access key 1 in the last {maximum_expiration_days} days ({access_key_1_last_used_date.days} days)." findings.append(report) @@ -56,6 +65,7 @@ class iam_user_accesskey_unused(Check): report.region = iam_client.region report.resource_id = user["user"] + "/AccessKey2" report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "FAIL" report.status_extended = f"User {user['user']} has not used access key 2 in the last {maximum_expiration_days} days ({access_key_2_last_used_date.days} days)." findings.append(report) @@ -65,6 +75,7 @@ class iam_user_accesskey_unused(Check): report.region = iam_client.region report.resource_id = user["user"] report.resource_arn = user["arn"] + report.resource_tags = user_tags report.status = "PASS" report.status_extended = f"User {user['user']} does not have unused access keys for {maximum_expiration_days} days." findings.append(report) diff --git a/prowler/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access.py b/prowler/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access.py index a3c03a8ee4..a3695ec86a 100644 --- a/prowler/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access.py +++ b/prowler/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access.py @@ -13,6 +13,11 @@ class iam_user_mfa_enabled_console_access(Check): report.resource_id = user["user"] report.resource_arn = user["arn"] report.region = iam_client.region + # Search user in iam_client.users to get tags + for iam_user in iam_client.users: + if iam_user.arn == user["arn"]: + report.resource_tags = iam_user.tags + break # check if the user has password enabled if user["password_enabled"] == "true": if user["mfa_active"] == "false": diff --git a/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.py b/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.py index de506c1645..2c3aaa30ea 100644 --- a/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.py +++ b/prowler/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key.py @@ -54,4 +54,9 @@ class iam_user_no_setup_initial_access_key(Check): report.resource_arn = user["arn"] report.status = status report.status_extended = status_extended + # Search user in iam_client.users to get tags + for iam_user in iam_client.users: + if iam_user.arn == user["arn"]: + report.resource_tags = iam_user.tags + break findings.append(report) diff --git a/prowler/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key.py b/prowler/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key.py index 93b661907b..94b40985b9 100644 --- a/prowler/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key.py +++ b/prowler/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key.py @@ -13,6 +13,11 @@ class iam_user_two_active_access_key(Check): report.resource_id = user["user"] report.resource_arn = user["arn"] report.region = iam_client.region + # Search user in iam_client.users to get tags + for iam_user in iam_client.users: + if iam_user.arn == user["arn"]: + report.resource_tags = iam_user.tags + break if ( user["access_key_1_active"] == "true" and user["access_key_2_active"] == "true" diff --git a/prowler/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials.py b/prowler/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials.py index d3657d5313..b352188cc0 100644 --- a/prowler/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials.py +++ b/prowler/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials.py @@ -17,6 +17,11 @@ class iam_user_with_temporary_credentials(Check): report.resource_id = user_name report.resource_arn = user_arn report.region = iam_client.region + # Search user in iam_client.users to get tags + for iam_user in iam_client.users: + if iam_user.arn == user_arn: + report.resource_tags = iam_user.tags + break report.status = "PASS" report.status_extended = f"User {user_name} doesn't have long lived credentials with access to other services than IAM or STS." diff --git a/tests/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts_test.py b/tests/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts_test.py index 2200d75a9e..a7dd4871a9 100644 --- a/tests/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts_test.py +++ b/tests/providers/aws/services/iam/iam_check_saml_providers_sts/iam_check_saml_providers_sts_test.py @@ -1,12 +1,31 @@ from unittest import mock +import botocore from boto3 import client from moto import mock_aws -from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider +from tests.providers.aws.utils import ( + AWS_ACCOUNT_NUMBER, + AWS_REGION_US_EAST_1, + set_mocked_aws_provider, +) + +orig = botocore.client.BaseClient._make_api_call + + +def mock_make_api_call(self, operation_name, kwarg): + if operation_name == "ListSAMLProviderTags": + return { + "Tags": [ + {"Key": "Name", "Value": "test"}, + {"Key": "Owner", "Value": "test"}, + ] + } + return orig(self, operation_name, kwarg) class Test_iam_check_saml_providers_sts: + @mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) @mock_aws def test_iam_check_saml_providers_sts(self): iam_client = client("iam") @@ -63,3 +82,46 @@ nTTxU4a7x1naFxzYXK1iQ1vMARKMjDb19QEJIEJKZlDK4uS7yMlf1nFS check = iam_check_saml_providers_sts() result = check.execute() assert result[0].status == "PASS" + assert result[0].resource_id == saml_provider_name + assert ( + result[0].resource_arn + == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:saml-provider/{saml_provider_name}" + ) + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test"}, + {"Key": "Owner", "Value": "test"}, + ] + assert result[0].region == AWS_REGION_US_EAST_1 + assert ( + result[0].status_extended + == f"SAML Provider {saml_provider_name} has been found." + ) + + @mock_aws + def test_iam_check_saml_providers_sts_no_saml_providers(self): + 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_check_saml_providers_sts.iam_check_saml_providers_sts.iam_client", + new=IAM(aws_provider), + ): + # Test Check + from prowler.providers.aws.services.iam.iam_check_saml_providers_sts.iam_check_saml_providers_sts import ( + iam_check_saml_providers_sts, + ) + + check = iam_check_saml_providers_sts() + result = check.execute() + assert result[0].status == "FAIL" + assert result[0].resource_id == AWS_ACCOUNT_NUMBER + assert ( + result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:root" + ) + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].status_extended == "No SAML Providers found." diff --git a/tests/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored_test.py b/tests/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored_test.py index d160435e41..70fd1a5f06 100644 --- a/tests/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored_test.py +++ b/tests/providers/aws/services/iam/iam_no_expired_server_certificates_stored/iam_no_expired_server_certificates_stored_test.py @@ -1,11 +1,23 @@ from re import search from unittest import mock +import botocore from boto3 import client from moto import mock_aws from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider +# Original botocore _make_api_call function +orig = botocore.client.BaseClient._make_api_call + + +# Mocked botocore _make_api_call function +def mock_make_api_call(self, operation_name, kwarg): + if operation_name == "ListServerCertificateTags": + return {"Tags": [{"Key": "Name", "Value": "certname"}]} + # If we don't want to patch the API call + return orig(self, operation_name, kwarg) + class Test_iam_no_expired_server_certificates_stored_test: @mock_aws @@ -31,6 +43,7 @@ class Test_iam_no_expired_server_certificates_stored_test: assert len(result) == 0 + @mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) @mock_aws def test_expired_certificate(self): iam_client = client("iam") @@ -39,6 +52,7 @@ class Test_iam_no_expired_server_certificates_stored_test: ServerCertificateName="certname", CertificateBody="certbody", PrivateKey="privatekey", + Tags=[{"Key": "Name", "Value": "certname"}], )["ServerCertificateMetadata"] from prowler.providers.aws.services.iam.iam_service import IAM @@ -68,3 +82,5 @@ class Test_iam_no_expired_server_certificates_stored_test: ) assert result[0].resource_id == cert["ServerCertificateId"] assert result[0].resource_arn == cert["Arn"] + assert result[0].resource_tags == [{"Key": "Name", "Value": "certname"}] + assert result[0].region == AWS_REGION_US_EAST_1 diff --git a/tests/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles_test.py b/tests/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles_test.py index c7e73d54de..1ca291c135 100644 --- a/tests/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles_test.py +++ b/tests/providers/aws/services/iam/iam_policy_attached_only_to_group_or_roles/iam_policy_attached_only_to_group_or_roles_test.py @@ -133,6 +133,9 @@ class Test_iam_policy_attached_only_to_group_or_roles: UserName=user, PolicyName=policyName, PolicyDocument=dumps(policyDocument) ) + # Tag the user + iam_client.tag_user(UserName=user, Tags=[{"Key": "tag1", "Value": "value1"}]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) from prowler.providers.aws.services.iam.iam_service import IAM @@ -160,6 +163,7 @@ class Test_iam_policy_attached_only_to_group_or_roles: result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:user/{user}" ) + assert result[0].resource_tags == [{"Key": "tag1", "Value": "value1"}] @mock_aws def test_iam_user_no_policies(self): @@ -168,6 +172,9 @@ class Test_iam_policy_attached_only_to_group_or_roles: user = "test_no_policies" iam_client.create_user(UserName=user) + # Tag the user + iam_client.tag_user(UserName=user, Tags=[{"Key": "tag1", "Value": "value1"}]) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) from prowler.providers.aws.services.iam.iam_service import IAM @@ -195,3 +202,4 @@ class Test_iam_policy_attached_only_to_group_or_roles: result[0].resource_arn == f"arn:aws:iam::{AWS_ACCOUNT_NUMBER}:user/{user}" ) + assert result[0].resource_tags == [{"Key": "tag1", "Value": "value1"}] diff --git a/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py b/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py index 7b20c6ec2e..57c697062f 100644 --- a/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py +++ b/tests/providers/aws/services/iam/iam_rotate_access_key_90_days/iam_rotate_access_key_90_days_test.py @@ -15,6 +15,8 @@ class Test_iam_rotate_access_key_90_days_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "test-tag", "Value": "test"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -43,6 +45,7 @@ class Test_iam_rotate_access_key_90_days_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "test-tag", "Value": "test"}] @mock_aws def test_user_access_key_1_not_rotated(self): @@ -53,6 +56,8 @@ class Test_iam_rotate_access_key_90_days_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "test-tag", "Value": "test"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -84,6 +89,7 @@ class Test_iam_rotate_access_key_90_days_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "test-tag", "Value": "test"}] @mock_aws def test_user_access_key_2_not_rotated(self): @@ -94,6 +100,8 @@ class Test_iam_rotate_access_key_90_days_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "test-tag", "Value": "test"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -125,6 +133,7 @@ class Test_iam_rotate_access_key_90_days_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "test-tag", "Value": "test"}] @mock_aws def test_user_both_access_keys_not_rotated(self): @@ -135,6 +144,8 @@ class Test_iam_rotate_access_key_90_days_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "test-tag", "Value": "test"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -171,6 +182,7 @@ class Test_iam_rotate_access_key_90_days_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "test-tag", "Value": "test"}] assert result[1].status == "FAIL" assert ( result[1].status_extended @@ -179,6 +191,7 @@ class Test_iam_rotate_access_key_90_days_test: assert result[1].resource_id == user assert result[1].resource_arn == arn assert result[1].region == AWS_REGION_US_EAST_1 + assert result[1].resource_tags == [{"Key": "test-tag", "Value": "test"}] @mock_aws def test_user_both_access_keys_rotated(self): @@ -189,6 +202,8 @@ class Test_iam_rotate_access_key_90_days_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "test-tag", "Value": "test"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -226,3 +241,4 @@ class Test_iam_rotate_access_key_90_days_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "test-tag", "Value": "test"}] diff --git a/tests/providers/aws/services/iam/iam_service_test.py b/tests/providers/aws/services/iam/iam_service_test.py index de0a2f1343..6367df390e 100644 --- a/tests/providers/aws/services/iam/iam_service_test.py +++ b/tests/providers/aws/services/iam/iam_service_test.py @@ -79,7 +79,6 @@ def mock_make_api_call(self, operation_name, kwargs): # Patch every AWS call using Boto3 @patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) class Test_IAM_Service: - # Test IAM Client @mock_aws def test_get_client(self): @@ -806,16 +805,18 @@ nTTxU4a7x1naFxzYXK1iQ1vMARKMjDb19QEJIEJKZlDK4uS7yMlf1nFS """ saml_provider_name = "test" - iam_client.create_saml_provider( + saml_arn = iam_client.create_saml_provider( SAMLMetadataDocument=xml_template, Name=saml_provider_name - ) + )["SAMLProviderArn"] # IAM client for this test class aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) iam = IAM(aws_provider) assert len(iam.saml_providers) == 1 - assert iam.saml_providers[0]["Arn"].split("/")[1] == saml_provider_name + assert saml_arn in iam.saml_providers + assert iam.saml_providers[saml_arn].name == saml_provider_name + assert iam.saml_providers[saml_arn].arn == saml_arn # Test IAM User Inline Policy @mock_aws diff --git a/tests/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused_test.py b/tests/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused_test.py index 0c96a4e2ec..76510303c5 100644 --- a/tests/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused_test.py +++ b/tests/providers/aws/services/iam/iam_user_accesskey_unused/iam_user_accesskey_unused_test.py @@ -18,6 +18,8 @@ class Test_iam_user_accesskey_unused_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider( @@ -54,6 +56,9 @@ class Test_iam_user_accesskey_unused_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test-user"} + ] @mock_aws def test_user_access_key_1_not_used(self): @@ -64,6 +69,8 @@ class Test_iam_user_accesskey_unused_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider( @@ -98,6 +105,9 @@ class Test_iam_user_accesskey_unused_test: assert result[0].resource_id == user + "/AccessKey1" assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test-user"} + ] @mock_aws def test_user_access_key_2_not_used(self): @@ -108,6 +118,8 @@ class Test_iam_user_accesskey_unused_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider( @@ -142,6 +154,9 @@ class Test_iam_user_accesskey_unused_test: assert result[0].resource_id == user + "/AccessKey2" assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test-user"} + ] @mock_aws def test_user_both_access_keys_not_used(self): @@ -152,6 +167,8 @@ class Test_iam_user_accesskey_unused_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider( @@ -191,6 +208,9 @@ class Test_iam_user_accesskey_unused_test: assert result[0].resource_id == user + "/AccessKey1" assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test-user"} + ] assert result[1].status == "FAIL" assert ( @@ -210,6 +230,8 @@ class Test_iam_user_accesskey_unused_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider( @@ -249,3 +271,6 @@ class Test_iam_user_accesskey_unused_test: assert result[0].resource_id == user assert result[0].resource_arn == arn assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test-user"} + ] diff --git a/tests/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access_test.py b/tests/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access_test.py index f0a66723c4..92588f9d38 100644 --- a/tests/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access_test.py +++ b/tests/providers/aws/services/iam/iam_user_mfa_enabled_console_access/iam_user_mfa_enabled_console_access_test.py @@ -70,6 +70,8 @@ class Test_iam_user_mfa_enabled_console_access_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -96,6 +98,7 @@ class Test_iam_user_mfa_enabled_console_access_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].resource_tags == [{"Key": "Name", "Value": "test-user"}] @mock_aws def test_user_password_console_and_mfa_enabled(self): @@ -103,6 +106,8 @@ class Test_iam_user_mfa_enabled_console_access_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -130,6 +135,7 @@ class Test_iam_user_mfa_enabled_console_access_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].resource_tags == [{"Key": "Name", "Value": "test-user"}] @mock_aws def test_user_password_console_enabled_and_mfa_not_enabled(self): @@ -137,6 +143,8 @@ class Test_iam_user_mfa_enabled_console_access_test: user = "test-user" arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": "test-user"}]) + from prowler.providers.aws.services.iam.iam_service import IAM aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) @@ -164,3 +172,4 @@ class Test_iam_user_mfa_enabled_console_access_test: ) assert result[0].resource_id == user assert result[0].resource_arn == arn + assert result[0].resource_tags == [{"Key": "Name", "Value": "test-user"}] diff --git a/tests/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key_test.py b/tests/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key_test.py index bcf74ffeab..f22a3d6292 100644 --- a/tests/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key_test.py +++ b/tests/providers/aws/services/iam/iam_user_no_setup_initial_access_key/iam_user_no_setup_initial_access_key_test.py @@ -2,22 +2,10 @@ from csv import DictReader from re import search from unittest import mock -from moto import mock_aws - from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider -AWS_ACCOUNT_NUMBER = "123456789012" - class Test_iam_user_no_setup_initial_access_key_test: - from tests.providers.aws.utils import ( - AWS_ACCOUNT_ARN, - AWS_ACCOUNT_NUMBER, - AWS_REGION_US_EAST_1, - set_mocked_aws_provider, - ) - - @mock_aws def test_setup_access_key_1_fail(self): raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated test_false_access_key_1,arn:aws:iam::123456789012:test_false_access_key_1,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A""" @@ -40,13 +28,28 @@ test_false_access_key_1,arn:aws:iam::123456789012:test_false_access_key_1,2022-0 ) service_client.credential_report = credential_list + service_client.users = [ + mock.MagicMock( + name="test_false_access_key_1", + arn="arn:aws:iam::123456789012:test_false_access_key_1", + tags=[{"Key": "Name", "Value": "test_false_access_key_1"}], + ) + ] check = iam_user_no_setup_initial_access_key() result = check.execute() assert result[0].status == "FAIL" assert search("has never used access key 1", result[0].status_extended) + assert result[0].resource_id == "test_false_access_key_1" + assert ( + result[0].resource_arn + == "arn:aws:iam::123456789012:test_false_access_key_1" + ) + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test_false_access_key_1"} + ] - @mock_aws def test_setup_access_key_2_fail(self): raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated test_false_access_key_2,arn:aws:iam::123456789012:test_false_access_key_2,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,true,N/A,N/A,N/A,N/A,false,N/A,false,N/A""" @@ -69,13 +72,28 @@ test_false_access_key_2,arn:aws:iam::123456789012:test_false_access_key_2,2022-0 ) service_client.credential_report = credential_list + service_client.users = [ + mock.MagicMock( + name="test_false_access_key_2", + arn="arn:aws:iam::123456789012:test_false_access_key_2", + tags=[{"Key": "Name", "Value": "test_false_access_key_2"}], + ) + ] check = iam_user_no_setup_initial_access_key() result = check.execute() assert result[0].status == "FAIL" assert search("has never used access key 2", result[0].status_extended) + assert result[0].resource_id == "test_false_access_key_2" + assert ( + result[0].resource_arn + == "arn:aws:iam::123456789012:test_false_access_key_2" + ) + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test_false_access_key_2"} + ] - @mock_aws def test_setup_both_access_keys_fail(self): raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated test_false_both_access_keys,arn:aws:iam::123456789012:test_false_both_access_keys,2022-04-17T14:59:38+00:00,true,no_information,not_supported,not_supported,false,true,N/A,N/A,N/A,N/A,true,N/A,N/A,N/A,N/A,false,N/A,false,N/A""" @@ -98,15 +116,39 @@ test_false_both_access_keys,arn:aws:iam::123456789012:test_false_both_access_key ) service_client.credential_report = credential_list + service_client.users = [ + mock.MagicMock( + name="test_false_both_access_keys", + arn="arn:aws:iam::123456789012:test_false_both_access_keys", + tags=[{"Key": "Name", "Value": "test_false_both_access_keys"}], + ) + ] check = iam_user_no_setup_initial_access_key() result = check.execute() assert result[0].status == "FAIL" assert search("has never used access key 1", result[0].status_extended) + assert result[0].resource_id == "test_false_both_access_keys" + assert ( + result[0].resource_arn + == "arn:aws:iam::123456789012:test_false_both_access_keys" + ) + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [ + {"Key": "Name", "Value": "test_false_both_access_keys"} + ] assert result[1].status == "FAIL" assert search("has never used access key 2", result[1].status_extended) + assert result[1].resource_id == "test_false_both_access_keys" + assert ( + result[1].resource_arn + == "arn:aws:iam::123456789012:test_false_both_access_keys" + ) + assert result[1].region == AWS_REGION_US_EAST_1 + assert result[1].resource_tags == [ + {"Key": "Name", "Value": "test_false_both_access_keys"} + ] - @mock_aws def test_setup_access_key_pass(self): raw_credential_report = r"""user,arn,user_creation_time,password_enabled,password_last_used,password_last_changed,password_next_rotation,mfa_active,access_key_1_active,access_key_1_last_rotated,access_key_1_last_used_date,access_key_1_last_used_region,access_key_1_last_used_service,access_key_2_active,access_key_2_last_rotated,access_key_2_last_used_date,access_key_2_last_used_region,access_key_2_last_used_service,cert_1_active,cert_1_last_rotated,cert_2_active,cert_2_last_rotated test_pass,arn:aws:iam::123456789012:test_pass,2022-02-17T14:59:38+00:00,not_supported,no_information,not_supported,not_supported,false,false,N/A,N/A,N/A,N/A,false,N/A,N/A,N/A,N/A,false,N/A,false,N/A""" @@ -129,6 +171,13 @@ test_pass,arn:aws:iam::123456789012:test_pass,2022-02-17T14:59:38+00:00,not_supp ) service_client.credential_report = credential_list + service_client.users = [ + mock.MagicMock( + name="test_pass", + arn="arn:aws:iam::123456789012:test_pass", + tags=[{"Key": "Name", "Value": "test_pass"}], + ) + ] check = iam_user_no_setup_initial_access_key() result = check.execute() @@ -137,3 +186,7 @@ test_pass,arn:aws:iam::123456789012:test_pass,2022-02-17T14:59:38+00:00,not_supp "does not have access keys or uses the access keys configured", result[0].status_extended, ) + assert result[0].resource_id == "test_pass" + assert result[0].resource_arn == "arn:aws:iam::123456789012:test_pass" + assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": "test_pass"}] diff --git a/tests/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key_test.py b/tests/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key_test.py index 2e23f272b1..6337334613 100644 --- a/tests/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key_test.py +++ b/tests/providers/aws/services/iam/iam_user_two_active_access_key/iam_user_two_active_access_key_test.py @@ -23,6 +23,7 @@ class Test_iam_user_two_active_access_key: iam_client = client("iam") user = "test1" user_arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": user}]) # Create Access Key 1 iam_client.create_access_key(UserName=user) # Create Access Key 2 @@ -57,6 +58,7 @@ class Test_iam_user_two_active_access_key: assert search( f"User {user} has 2 active access keys.", result[0].status_extended ) + assert result[0].resource_tags == [{"Key": "Name", "Value": user}] @mock_aws def test_iam_user_one_active_access_key(self): @@ -64,6 +66,7 @@ class Test_iam_user_two_active_access_key: iam_client = client("iam") user = "test1" user_arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": user}]) # Create Access Key 1 iam_client.create_access_key(UserName=user) @@ -94,6 +97,7 @@ class Test_iam_user_two_active_access_key: f"User {user} does not have 2 active access keys.", result[0].status_extended, ) + assert result[0].resource_tags == [{"Key": "Name", "Value": user}] @mock_aws def test_iam_user_without_active_access_key(self): @@ -101,6 +105,7 @@ class Test_iam_user_two_active_access_key: iam_client = client("iam") user = "test1" user_arn = iam_client.create_user(UserName=user)["User"]["Arn"] + iam_client.tag_user(UserName=user, Tags=[{"Key": "Name", "Value": user}]) from prowler.providers.aws.services.iam.iam_service import IAM @@ -129,6 +134,7 @@ class Test_iam_user_two_active_access_key: f"User {user} does not have 2 active access keys.", result[0].status_extended, ) + assert result[0].resource_tags == [{"Key": "Name", "Value": user}] @mock_aws def test_iam_no_users(self): diff --git a/tests/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials_test.py b/tests/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials_test.py index dd7848d36d..e1b9c31587 100644 --- a/tests/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials_test.py +++ b/tests/providers/aws/services/iam/iam_user_with_temporary_credentials/iam_user_with_temporary_credentials_test.py @@ -16,6 +16,13 @@ class Test_iam_user_with_temporary_credentials: iam_client.access_keys_metadata = {} iam_client.last_accessed_services = {} + iam_client.users = [ + mock.MagicMock( + arn=IAM_USER_ARN, + tags=[{"Key": "Name", "Value": IAM_USER_NAME}], + ) + ] + # Generate temporary credentials usage iam_client.user_temporary_credentials_usage = {} iam_client._get_user_temporary_credentials_usage = ( @@ -45,6 +52,13 @@ class Test_iam_user_with_temporary_credentials: iam_client.access_keys_metadata = {USER_DATA: []} iam_client.last_accessed_services = {USER_DATA: []} + iam_client.users = [ + mock.MagicMock( + arn=IAM_USER_ARN, + tags=[{"Key": "Name", "Value": IAM_USER_NAME}], + ) + ] + # Generate temporary credentials usage iam_client.user_temporary_credentials_usage = {} iam_client._get_user_temporary_credentials_usage = ( @@ -74,6 +88,7 @@ class Test_iam_user_with_temporary_credentials: assert result[0].resource_id == IAM_USER_NAME assert result[0].resource_arn == IAM_USER_ARN assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": IAM_USER_NAME}] def test_user_access_keys_no_accesed_services(self): iam_client = mock.MagicMock @@ -82,6 +97,13 @@ class Test_iam_user_with_temporary_credentials: iam_client.access_keys_metadata = {USER_DATA: [{"AccessKeyId": 1}]} iam_client.last_accessed_services = {USER_DATA: []} + iam_client.users = [ + mock.MagicMock( + arn=IAM_USER_ARN, + tags=[{"Key": "Name", "Value": IAM_USER_NAME}], + ) + ] + # Generate temporary credentials usage iam_client.user_temporary_credentials_usage = {} iam_client._get_user_temporary_credentials_usage = ( @@ -111,6 +133,7 @@ class Test_iam_user_with_temporary_credentials: assert result[0].resource_id == IAM_USER_NAME assert result[0].resource_arn == IAM_USER_ARN assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": IAM_USER_NAME}] def test_user_access_keys_accesed_services_sts(self): iam_client = mock.MagicMock @@ -119,6 +142,13 @@ class Test_iam_user_with_temporary_credentials: iam_client.access_keys_metadata = {USER_DATA: [{"AccessKeyId": 1}]} iam_client.last_accessed_services = {USER_DATA: [{"ServiceNamespace": "sts"}]} + iam_client.users = [ + mock.MagicMock( + arn=IAM_USER_ARN, + tags=[{"Key": "Name", "Value": IAM_USER_NAME}], + ) + ] + # Generate temporary credentials usage iam_client.user_temporary_credentials_usage = {} iam_client._get_user_temporary_credentials_usage = ( @@ -148,6 +178,7 @@ class Test_iam_user_with_temporary_credentials: assert result[0].resource_id == IAM_USER_NAME assert result[0].resource_arn == IAM_USER_ARN assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": IAM_USER_NAME}] def test_access_keys_with_iam_and_sts(self): iam_client = mock.MagicMock @@ -158,6 +189,13 @@ class Test_iam_user_with_temporary_credentials: USER_DATA: [{"ServiceNamespace": "sts"}, {"ServiceNamespace": "iam"}] } + iam_client.users = [ + mock.MagicMock( + arn=IAM_USER_ARN, + tags=[{"Key": "Name", "Value": IAM_USER_NAME}], + ) + ] + # Generate temporary credentials usage iam_client.user_temporary_credentials_usage = {} iam_client._get_user_temporary_credentials_usage = ( @@ -187,6 +225,7 @@ class Test_iam_user_with_temporary_credentials: assert result[0].resource_id == IAM_USER_NAME assert result[0].resource_arn == IAM_USER_ARN assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": IAM_USER_NAME}] def test_access_keys_with_iam_and_ec2(self): iam_client = mock.MagicMock @@ -197,6 +236,13 @@ class Test_iam_user_with_temporary_credentials: USER_DATA: [{"ServiceNamespace": "iam"}, {"ServiceNamespace": "ec2"}] } + iam_client.users = [ + mock.MagicMock( + arn=IAM_USER_ARN, + tags=[{"Key": "Name", "Value": IAM_USER_NAME}], + ) + ] + # Generate temporary credentials usage iam_client.user_temporary_credentials_usage = {} iam_client._get_user_temporary_credentials_usage = ( @@ -226,3 +272,4 @@ class Test_iam_user_with_temporary_credentials: assert result[0].resource_id == IAM_USER_NAME assert result[0].resource_arn == IAM_USER_ARN assert result[0].region == AWS_REGION_US_EAST_1 + assert result[0].resource_tags == [{"Key": "Name", "Value": IAM_USER_NAME}]