diff --git a/prowler/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks.py b/prowler/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks.py index a903d7c396..751433a208 100644 --- a/prowler/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks.py +++ b/prowler/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks.py @@ -8,26 +8,26 @@ class iam_custom_role_has_permissions_to_administer_resource_locks(Check): def execute(self) -> Check_Report_Azure: findings = [] for subscription, roles in iam_client.custom_roles.items(): - for role in roles: + exits_role_with_permission_over_locks = False + + for custom_role in roles: + if exits_role_with_permission_over_locks: + break report = Check_Report_Azure(self.metadata()) report.subscription = subscription - report.resource_id = role.id - report.resource_name = role.name - has_lock_permission = False - for permission_item in role.permissions: - if has_lock_permission: + report.resource_id = custom_role.id + report.resource_name = custom_role.name + report.status = "FAIL" + report.status_extended = f"Role {custom_role.name} from subscription {subscription} has no permission to administer resource locks." + + for permission_item in custom_role.permissions: + if exits_role_with_permission_over_locks: break for action in permission_item.actions: - if has_lock_permission: - break if search("^Microsoft.Authorization/locks/.*", action): report.status = "PASS" - report.status_extended = f"Role {role.name} from subscription {subscription} has permission to administer resource locks." - has_lock_permission = True + report.status_extended = f"Role {custom_role.name} from subscription {subscription} has permission to administer resource locks." + exits_role_with_permission_over_locks = True break - else: - report.status = "FAIL" - report.status_extended = f"Role {role.name} from subscription {subscription} has no permission to administer resource locks." - break - findings.append(report) + findings.append(report) return findings diff --git a/prowler/providers/azure/services/iam/iam_subscription_roles_owner_custom_not_created/iam_subscription_roles_owner_custom_not_created.py b/prowler/providers/azure/services/iam/iam_subscription_roles_owner_custom_not_created/iam_subscription_roles_owner_custom_not_created.py index 85bea3b492..3fbcce9264 100644 --- a/prowler/providers/azure/services/iam/iam_subscription_roles_owner_custom_not_created/iam_subscription_roles_owner_custom_not_created.py +++ b/prowler/providers/azure/services/iam/iam_subscription_roles_owner_custom_not_created/iam_subscription_roles_owner_custom_not_created.py @@ -8,20 +8,20 @@ class iam_subscription_roles_owner_custom_not_created(Check): def execute(self) -> Check_Report_Azure: findings = [] for subscription, roles in iam_client.custom_roles.items(): - for role in roles: + for custom_role in roles: report = Check_Report_Azure(self.metadata()) report.subscription = subscription - report.resource_id = role.id - report.resource_name = role.name + report.resource_id = custom_role.id + report.resource_name = custom_role.name report.status = "PASS" - report.status_extended = f"Role {role.name} from subscription {subscription} is not a custom owner role." - for scope in role.assignable_scopes: + report.status_extended = f"Role {custom_role.name} from subscription {subscription} is not a custom owner role." + for scope in custom_role.assignable_scopes: if search("^/.*", scope): - for permission_item in role.permissions: + for permission_item in custom_role.permissions: for action in permission_item.actions: if action == "*": report.status = "FAIL" - report.status_extended = f"Role {role.name} from subscription {subscription} is a custom owner role." + report.status_extended = f"Role {custom_role.name} from subscription {subscription} is a custom owner role." break findings.append(report) diff --git a/tests/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks_test.py b/tests/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks_test.py index d5f58059f6..bd454aafed 100644 --- a/tests/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks_test.py +++ b/tests/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks_test.py @@ -122,3 +122,67 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks: == defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][0].id ) assert result[0].resource_name == role_name + + def test_iam_custom_owner_roles_created_with_lock_administration_permissions( + self, + ): + defender_client = mock.MagicMock + role_name = "test-role" + role_name2 = "test-role2" + defender_client.custom_roles = { + AZURE_SUBSCRIPTION_ID: [ + Role( + id=str(uuid4()), + name=role_name, + type="CustomRole", + assignable_scopes=["/.*", "/test"], + permissions=[ + Permission( + actions=[ + "Microsoft.Authorization/locks/*", + "microsoft.aadiam/azureADMetrics/read", + ] + ) + ], + ), + Role( + id=str(uuid4()), + name=role_name2, + type="CustomRole", + assignable_scopes=["/.*", "/test"], + permissions=[ + Permission( + actions=[ + "Microsoft.Authorization/locks/*", + "microsoft.aadiam/azureADMetrics/read", + ] + ) + ], + ), + ] + } + + with mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_azure_provider(), + ), mock.patch( + "prowler.providers.azure.services.iam.iam_custom_role_has_permissions_to_administer_resource_locks.iam_custom_role_has_permissions_to_administer_resource_locks.iam_client", + new=defender_client, + ): + from prowler.providers.azure.services.iam.iam_custom_role_has_permissions_to_administer_resource_locks.iam_custom_role_has_permissions_to_administer_resource_locks import ( + iam_custom_role_has_permissions_to_administer_resource_locks, + ) + + check = iam_custom_role_has_permissions_to_administer_resource_locks() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == f"Role {role_name} from subscription {AZURE_SUBSCRIPTION_ID} has permission to administer resource locks." + ) + assert result[0].subscription == AZURE_SUBSCRIPTION_ID + assert ( + result[0].resource_id + == defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][0].id + )