mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 04:21:52 +00:00
feat(azure): add new check iam_role_user_access_admin_restricted (#8040)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
This commit is contained in:
committed by
GitHub
parent
a626e41162
commit
b572575c8d
+9
-3
@@ -41,9 +41,15 @@ class app_function_identity_without_admin_privileges(Check):
|
||||
USER_ACCESS_ADMINISTRATOR_ROLE_ID,
|
||||
]
|
||||
):
|
||||
for role in iam_client.roles[subscription_name]:
|
||||
if role.id.split("/")[-1] == role_assignment.role_id:
|
||||
admin_roles_assigned.append(role.name)
|
||||
admin_roles_assigned.append(
|
||||
getattr(
|
||||
iam_client.roles[subscription_name].get(
|
||||
f"/subscriptions/{iam_client.subscriptions[subscription_name]}/providers/Microsoft.Authorization/roleDefinitions/{role_assignment.role_id}"
|
||||
),
|
||||
"name",
|
||||
"",
|
||||
)
|
||||
)
|
||||
|
||||
if admin_roles_assigned:
|
||||
report.status = "FAIL"
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ class entra_user_with_vm_access_has_mfa(Check):
|
||||
findings = []
|
||||
|
||||
for users in entra_client.users.values():
|
||||
for user_domain_name, user in users.items():
|
||||
for user in users.values():
|
||||
for (
|
||||
subscription_name,
|
||||
role_assigns,
|
||||
|
||||
+1
-1
@@ -10,7 +10,7 @@ class iam_custom_role_has_permissions_to_administer_resource_locks(Check):
|
||||
for subscription, roles in iam_client.custom_roles.items():
|
||||
exits_role_with_permission_over_locks = False
|
||||
|
||||
for custom_role in roles:
|
||||
for custom_role in roles.values():
|
||||
if exits_role_with_permission_over_locks:
|
||||
break
|
||||
report = Check_Report_Azure(
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "azure",
|
||||
"CheckID": "iam_role_user_access_admin_restricted",
|
||||
"CheckTitle": "Ensure 'User Access Administrator' role is restricted",
|
||||
"CheckType": [],
|
||||
"ServiceName": "iam",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "high",
|
||||
"ResourceType": "AzureIAMRoleassignment",
|
||||
"Description": "Checks for active assignments of the highly privileged 'User Access Administrator' role in Azure subscriptions.",
|
||||
"Risk": "Persistent assignment of this role can lead to privilege escalation and unauthorized access, increasing the risk of security breaches.",
|
||||
"RelatedUrl": "https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles/privileged#user-access-administrator",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "az role assignment delete --role 'User Access Administrator' --scope '/subscriptions/<subscription_id>'",
|
||||
"NativeIaC": "",
|
||||
"Other": "",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Remove 'User Access Administrator' role assignments immediately after use to minimize security risks.",
|
||||
"Url": "https://learn.microsoft.com/en-us/azure/role-based-access-control/elevate-access-global-admin?tabs=azure-portal%2Centra-audit-logs"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
from prowler.lib.check.models import Check, Check_Report_Azure
|
||||
from prowler.providers.azure.services.iam.iam_client import iam_client
|
||||
|
||||
|
||||
class iam_role_user_access_admin_restricted(Check):
|
||||
def execute(self):
|
||||
findings = []
|
||||
|
||||
for subscription_name, assignments in iam_client.role_assignments.items():
|
||||
for assignment in assignments.values():
|
||||
role_assignment_name = getattr(
|
||||
iam_client.roles[subscription_name].get(
|
||||
f"/subscriptions/{iam_client.subscriptions[subscription_name]}/providers/Microsoft.Authorization/roleDefinitions/{assignment.role_id}"
|
||||
),
|
||||
"name",
|
||||
"",
|
||||
)
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource=assignment
|
||||
)
|
||||
report.subscription = subscription_name
|
||||
if role_assignment_name == "User Access Administrator":
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Role assignment {assignment.name} in subscription {subscription_name} grants User Access Administrator role to {getattr(assignment, 'agent_type', '')} {getattr(assignment, 'agent_id', '')}."
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Role assignment {assignment.name} in subscription {subscription_name} does not grant User Access Administrator role."
|
||||
findings.append(report)
|
||||
return findings
|
||||
@@ -20,45 +20,40 @@ class IAM(AzureService):
|
||||
custom_roles = {}
|
||||
for subscription, client in self.clients.items():
|
||||
try:
|
||||
builtin_roles.update({subscription: []})
|
||||
custom_roles.update({subscription: []})
|
||||
builtin_roles.update({subscription: {}})
|
||||
custom_roles.update({subscription: {}})
|
||||
all_roles = client.role_definitions.list(
|
||||
scope=f"/subscriptions/{self.subscriptions[subscription]}",
|
||||
)
|
||||
for role in all_roles:
|
||||
if role.role_type == "CustomRole":
|
||||
custom_roles[subscription].append(
|
||||
Role(
|
||||
id=role.id,
|
||||
name=role.role_name,
|
||||
type=role.role_type,
|
||||
assignable_scopes=role.assignable_scopes,
|
||||
permissions=[
|
||||
Permission(
|
||||
condition=getattr(permission, "condition", ""),
|
||||
condition_version=getattr(
|
||||
permission, "condition_version", ""
|
||||
),
|
||||
actions=getattr(permission, "actions", []),
|
||||
)
|
||||
for permission in getattr(role, "permissions", [])
|
||||
],
|
||||
)
|
||||
custom_roles[subscription][role.id] = Role(
|
||||
id=role.id,
|
||||
name=role.role_name,
|
||||
type=role.role_type,
|
||||
assignable_scopes=role.assignable_scopes,
|
||||
permissions=[
|
||||
Permission(
|
||||
condition=getattr(permission, "condition", ""),
|
||||
condition_version=getattr(
|
||||
permission, "condition_version", ""
|
||||
),
|
||||
actions=getattr(permission, "actions", []),
|
||||
)
|
||||
for permission in getattr(role, "permissions", [])
|
||||
],
|
||||
)
|
||||
else:
|
||||
builtin_roles[subscription].append(
|
||||
Role(
|
||||
id=role.id,
|
||||
name=role.role_name,
|
||||
type=role.role_type,
|
||||
assignable_scopes=role.assignable_scopes,
|
||||
permissions=role.permissions,
|
||||
)
|
||||
builtin_roles[subscription][role.id] = Role(
|
||||
id=role.id,
|
||||
name=role.role_name,
|
||||
type=role.role_type,
|
||||
assignable_scopes=role.assignable_scopes,
|
||||
permissions=role.permissions,
|
||||
)
|
||||
except Exception as error:
|
||||
logger.error(f"Subscription name: {subscription}")
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
f"Subscription name: {subscription} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
return builtin_roles, custom_roles
|
||||
|
||||
@@ -75,6 +70,9 @@ class IAM(AzureService):
|
||||
role_assignments[subscription].update(
|
||||
{
|
||||
role_assignment.id: RoleAssignment(
|
||||
id=role_assignment.id,
|
||||
name=role_assignment.name,
|
||||
scope=role_assignment.scope,
|
||||
agent_id=role_assignment.principal_id,
|
||||
agent_type=role_assignment.principal_type,
|
||||
role_id=role_assignment.role_definition_id.split("/")[
|
||||
@@ -84,9 +82,8 @@ class IAM(AzureService):
|
||||
}
|
||||
)
|
||||
except Exception as error:
|
||||
logger.error(f"Subscription name: {subscription}")
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
f"Subscription name: {subscription} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
return role_assignments
|
||||
|
||||
@@ -109,6 +106,21 @@ class Role:
|
||||
|
||||
@dataclass
|
||||
class RoleAssignment:
|
||||
"""
|
||||
Represents an Azure Role Assignment.
|
||||
|
||||
Attributes:
|
||||
id: The unique identifier of the role assignment.
|
||||
name: The name of the role assignment.
|
||||
scope: The scope at which the role assignment applies.
|
||||
agent_id: The principal (user, group, service principal, etc.) ID assigned the role.
|
||||
agent_type: The type of the principal. Known values: "User", "Group", "ServicePrincipal", "ForeignGroup", and "Device".
|
||||
role_id: The ID of the role definition assigned.
|
||||
"""
|
||||
|
||||
id: str
|
||||
name: str
|
||||
scope: str
|
||||
agent_id: str
|
||||
agent_type: str
|
||||
role_id: str
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ 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 custom_role in roles:
|
||||
for custom_role in roles.values():
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource=custom_role
|
||||
)
|
||||
|
||||
+31
-19
@@ -144,24 +144,29 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
|
||||
iam_client.role_assignments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"1": RoleAssignment(
|
||||
role_id="1",
|
||||
"role-assignment-id-1": RoleAssignment(
|
||||
id="role-assignment-id-1",
|
||||
name="role-assignment-name-1",
|
||||
scope="/subscriptions/{}/resourceGroups/rg/providers/Microsoft.Web/sites/function1".format(
|
||||
AZURE_SUBSCRIPTION_ID
|
||||
),
|
||||
agent_id="123",
|
||||
agent_type="User",
|
||||
role_id="role-id-1",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
iam_client.roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id="1",
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"role-id-1": Role(
|
||||
id="role-id-1",
|
||||
name="role1",
|
||||
type="User",
|
||||
type="BuiltInRole",
|
||||
assignable_scopes=[],
|
||||
permissions=[],
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
check = app_function_identity_without_admin_privileges()
|
||||
@@ -205,9 +210,9 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
)
|
||||
|
||||
function_id = str(uuid4())
|
||||
|
||||
function_scope = f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/resourceGroups/rg/providers/Microsoft.Web/sites/function1"
|
||||
app_client.functions = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"subscription-name-1": {
|
||||
function_id: FunctionApp(
|
||||
id=function_id,
|
||||
name="function1",
|
||||
@@ -223,26 +228,33 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
}
|
||||
}
|
||||
|
||||
iam_client.subscriptions = {
|
||||
"subscription-name-1": AZURE_SUBSCRIPTION_ID,
|
||||
}
|
||||
|
||||
iam_client.role_assignments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"1": RoleAssignment(
|
||||
role_id=USER_ACCESS_ADMINISTRATOR_ROLE_ID,
|
||||
"subscription-name-1": {
|
||||
"role-assignment-id-2": RoleAssignment(
|
||||
id="role-assignment-id-2",
|
||||
name="role-assignment-name-2",
|
||||
scope=function_scope,
|
||||
agent_id="123",
|
||||
agent_type="User",
|
||||
role_id=USER_ACCESS_ADMINISTRATOR_ROLE_ID,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
iam_client.roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id=USER_ACCESS_ADMINISTRATOR_ROLE_ID,
|
||||
"subscription-name-1": {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{USER_ACCESS_ADMINISTRATOR_ROLE_ID}": Role(
|
||||
id=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{USER_ACCESS_ADMINISTRATOR_ROLE_ID}",
|
||||
name="User Access Administrator",
|
||||
type="User",
|
||||
type="BuiltInRole",
|
||||
assignable_scopes=[],
|
||||
permissions=[],
|
||||
)
|
||||
]
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
check = app_function_identity_without_admin_privileges()
|
||||
@@ -255,5 +267,5 @@ class Test_app_function_identity_without_admin_privileges:
|
||||
)
|
||||
assert result[0].resource_id == function_id
|
||||
assert result[0].resource_name == "function1"
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].subscription == "subscription-name-1"
|
||||
assert result[0].location == "West Europe"
|
||||
|
||||
+12
@@ -75,6 +75,9 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
iam_client.role_assignments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
role_assigment_id: RoleAssignment(
|
||||
id=role_assigment_id,
|
||||
name="test",
|
||||
scope=AZURE_SUBSCRIPTION_ID,
|
||||
role_id=VIRTUAL_MACHINE_ADMINISTRATOR_LOGIN_ROLE_ID,
|
||||
agent_type="User",
|
||||
agent_id=user_id,
|
||||
@@ -149,6 +152,9 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
iam_client.role_assignments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
role_assigment_id: RoleAssignment(
|
||||
id=role_assigment_id,
|
||||
name="test",
|
||||
scope=AZURE_SUBSCRIPTION_ID,
|
||||
role_id=VIRTUAL_MACHINE_ADMINISTRATOR_LOGIN_ROLE_ID,
|
||||
agent_type="User",
|
||||
agent_id=user_id,
|
||||
@@ -216,6 +222,9 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
iam_client.role_assignments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
role_assigment_id: RoleAssignment(
|
||||
id=role_assigment_id,
|
||||
name="test",
|
||||
scope=AZURE_SUBSCRIPTION_ID,
|
||||
role_id=VIRTUAL_MACHINE_ADMINISTRATOR_LOGIN_ROLE_ID,
|
||||
agent_type="User",
|
||||
agent_id=user_id,
|
||||
@@ -269,6 +278,9 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
iam_client.role_assignments = {
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
role_assigment_id: RoleAssignment(
|
||||
id=role_assigment_id,
|
||||
name="test",
|
||||
scope=AZURE_SUBSCRIPTION_ID,
|
||||
role_id=str(uuid4()),
|
||||
agent_type="User",
|
||||
agent_id=user_id,
|
||||
|
||||
+24
-19
@@ -1,5 +1,4 @@
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from azure.mgmt.authorization.v2022_04_01.models import Permission
|
||||
|
||||
@@ -39,9 +38,9 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
defender_client = mock.MagicMock
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id=str(uuid4()),
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"test-role-id": Role(
|
||||
id="test-role-id",
|
||||
name=role_name,
|
||||
type="CustomRole",
|
||||
assignable_scopes=["/.*", "/test"],
|
||||
@@ -54,7 +53,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
)
|
||||
],
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -82,7 +81,9 @@ class Test_iam_custom_role_has_permissions_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
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][
|
||||
"test-role-id"
|
||||
].id
|
||||
)
|
||||
assert result[0].resource_name == role_name
|
||||
|
||||
@@ -92,15 +93,15 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
defender_client = mock.MagicMock
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id=str(uuid4()),
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"test-role-id": Role(
|
||||
id="test-role-id",
|
||||
name=role_name,
|
||||
type="CustomRole",
|
||||
assignable_scopes=["/*"],
|
||||
permissions=[Permission(actions=["*"])],
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -128,7 +129,9 @@ class Test_iam_custom_role_has_permissions_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
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][
|
||||
"test-role-id"
|
||||
].id
|
||||
)
|
||||
assert result[0].resource_name == role_name
|
||||
|
||||
@@ -139,9 +142,9 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
role_name = "test-role"
|
||||
role_name2 = "test-role2"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id=str(uuid4()),
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"test-role-id": Role(
|
||||
id="test-role-id",
|
||||
name=role_name,
|
||||
type="CustomRole",
|
||||
assignable_scopes=["/.*", "/test"],
|
||||
@@ -154,8 +157,8 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
)
|
||||
],
|
||||
),
|
||||
Role(
|
||||
id=str(uuid4()),
|
||||
"test-role-id2": Role(
|
||||
id="test-role-id2",
|
||||
name=role_name2,
|
||||
type="CustomRole",
|
||||
assignable_scopes=["/.*", "/test"],
|
||||
@@ -168,7 +171,7 @@ class Test_iam_custom_role_has_permissions_to_administer_resource_locks:
|
||||
)
|
||||
],
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -196,12 +199,14 @@ class Test_iam_custom_role_has_permissions_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
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][
|
||||
"test-role-id"
|
||||
].id
|
||||
)
|
||||
|
||||
def test_iam_custom_roles_empty_list_but_with_key(self):
|
||||
defender_client = mock.MagicMock
|
||||
defender_client.custom_roles = {AZURE_SUBSCRIPTION_ID: []}
|
||||
defender_client.custom_roles = {AZURE_SUBSCRIPTION_ID: {}}
|
||||
|
||||
with (
|
||||
mock.patch(
|
||||
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from prowler.providers.azure.services.iam.iam_service import Role, RoleAssignment
|
||||
from tests.providers.azure.azure_fixtures import (
|
||||
AZURE_SUBSCRIPTION_ID,
|
||||
set_mocked_azure_provider,
|
||||
)
|
||||
|
||||
|
||||
class Test_iam_role_user_access_admin_restricted:
|
||||
def test_iam_no_role_assignments(self):
|
||||
iam_client = mock.MagicMock
|
||||
iam_client.role_assignments = {}
|
||||
iam_client.roles = {}
|
||||
|
||||
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_role_user_access_admin_restricted.iam_role_user_access_admin_restricted.iam_client",
|
||||
new=iam_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.iam.iam_role_user_access_admin_restricted.iam_role_user_access_admin_restricted import (
|
||||
iam_role_user_access_admin_restricted,
|
||||
)
|
||||
|
||||
check = iam_role_user_access_admin_restricted()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
def test_iam_user_access_administrator_role_assigned(self):
|
||||
iam_client = mock.MagicMock
|
||||
role_id = str(uuid4())
|
||||
role_assignment_id = str(uuid4())
|
||||
agent_id = str(uuid4())
|
||||
role_name = "User Access Administrator"
|
||||
|
||||
iam_client.subscriptions = {
|
||||
"subscription-name-1": AZURE_SUBSCRIPTION_ID,
|
||||
}
|
||||
|
||||
iam_client.role_assignments = {
|
||||
"subscription-name-1": {
|
||||
role_assignment_id: RoleAssignment(
|
||||
id=role_assignment_id,
|
||||
name="test-assignment",
|
||||
scope=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}",
|
||||
agent_id=agent_id,
|
||||
agent_type="User",
|
||||
role_id=role_id,
|
||||
)
|
||||
}
|
||||
}
|
||||
iam_client.roles = {
|
||||
"subscription-name-1": {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{role_id}": Role(
|
||||
id=role_id,
|
||||
name=role_name,
|
||||
type="BuiltInRole",
|
||||
assignable_scopes=[f"/subscriptions/{AZURE_SUBSCRIPTION_ID}"],
|
||||
permissions=[],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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_role_user_access_admin_restricted.iam_role_user_access_admin_restricted.iam_client",
|
||||
new=iam_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.iam.iam_role_user_access_admin_restricted.iam_role_user_access_admin_restricted import (
|
||||
iam_role_user_access_admin_restricted,
|
||||
)
|
||||
|
||||
check = iam_role_user_access_admin_restricted()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== f"Role assignment test-assignment in subscription subscription-name-1 grants User Access Administrator role to User {agent_id}."
|
||||
)
|
||||
assert result[0].subscription == "subscription-name-1"
|
||||
assert result[0].resource_id == role_assignment_id
|
||||
|
||||
def test_iam_non_user_access_administrator_role_assigned(self):
|
||||
iam_client = mock.MagicMock
|
||||
role_id = str(uuid4())
|
||||
role_assignment_id = str(uuid4())
|
||||
agent_id = str(uuid4())
|
||||
role_name = "Reader"
|
||||
|
||||
iam_client.subscriptions = {
|
||||
"subscription-name-1": AZURE_SUBSCRIPTION_ID,
|
||||
}
|
||||
|
||||
iam_client.role_assignments = {
|
||||
"subscription-name-1": {
|
||||
role_assignment_id: RoleAssignment(
|
||||
id=role_assignment_id,
|
||||
name="test-assignment",
|
||||
scope=f"/subscriptions/{AZURE_SUBSCRIPTION_ID}",
|
||||
agent_id=agent_id,
|
||||
agent_type="User",
|
||||
role_id=role_id,
|
||||
)
|
||||
}
|
||||
}
|
||||
iam_client.roles = {
|
||||
"subscription-name-1": {
|
||||
f"/subscriptions/{AZURE_SUBSCRIPTION_ID}/providers/Microsoft.Authorization/roleDefinitions/{role_id}": Role(
|
||||
id=role_id,
|
||||
name=role_name,
|
||||
type="BuiltInRole",
|
||||
assignable_scopes=[f"/subscriptions/{AZURE_SUBSCRIPTION_ID}"],
|
||||
permissions=[],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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_role_user_access_admin_restricted.iam_role_user_access_admin_restricted.iam_client",
|
||||
new=iam_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.iam.iam_role_user_access_admin_restricted.iam_role_user_access_admin_restricted import (
|
||||
iam_role_user_access_admin_restricted,
|
||||
)
|
||||
|
||||
check = iam_role_user_access_admin_restricted()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Role assignment test-assignment in subscription subscription-name-1 does not grant User Access Administrator role."
|
||||
)
|
||||
assert result[0].subscription == "subscription-name-1"
|
||||
assert result[0].resource_id == role_assignment_id
|
||||
+14
-11
@@ -1,5 +1,4 @@
|
||||
from unittest import mock
|
||||
from uuid import uuid4
|
||||
|
||||
from azure.mgmt.authorization.v2022_04_01.models import Permission
|
||||
|
||||
@@ -37,15 +36,15 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
defender_client = mock.MagicMock
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id=str(uuid4()),
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"test-role-id": Role(
|
||||
id="test-role-id",
|
||||
name=role_name,
|
||||
type="CustomRole",
|
||||
assignable_scopes=["/*"],
|
||||
permissions=[Permission(actions="*")],
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -73,7 +72,9 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
result[0].resource_id
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][0].id
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][
|
||||
"test-role-id"
|
||||
].id
|
||||
)
|
||||
assert result[0].resource_name == role_name
|
||||
|
||||
@@ -81,15 +82,15 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
defender_client = mock.MagicMock
|
||||
role_name = "test-role"
|
||||
defender_client.custom_roles = {
|
||||
AZURE_SUBSCRIPTION_ID: [
|
||||
Role(
|
||||
id=str(uuid4()),
|
||||
AZURE_SUBSCRIPTION_ID: {
|
||||
"test-role-id": Role(
|
||||
id="test-role-id",
|
||||
name=role_name,
|
||||
type="type-role",
|
||||
assignable_scopes=[""],
|
||||
permissions=[Permission()],
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
with (
|
||||
@@ -117,6 +118,8 @@ class Test_iam_subscription_roles_owner_custom_not_created:
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert (
|
||||
result[0].resource_id
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][0].id
|
||||
== defender_client.custom_roles[AZURE_SUBSCRIPTION_ID][
|
||||
"test-role-id"
|
||||
].id
|
||||
)
|
||||
assert result[0].resource_name == role_name
|
||||
|
||||
Reference in New Issue
Block a user