chore(IAM): Improve IAM checks for Azure (#4061)

This commit is contained in:
Rubén De la Torre Vico
2024-05-22 16:19:13 +02:00
committed by GitHub
parent d1632d71c2
commit c118e34ada
3 changed files with 86 additions and 22 deletions
@@ -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
@@ -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)
@@ -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
)