mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-24 13:01:56 +00:00
feat(entra): extract Entra resource metadata automated (#6542)
Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
This commit is contained in:
committed by
GitHub
parent
43fd9ee94e
commit
ee7d32d460
+14
-12
@@ -11,16 +11,7 @@ class entra_conditional_access_policy_require_mfa_for_management_api(Check):
|
||||
tenant_name,
|
||||
conditional_access_policies,
|
||||
) in entra_client.conditional_access_policy.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report.subscription = f"Tenant: {tenant_name}"
|
||||
report.resource_name = "Conditional Access Policy"
|
||||
report.resource_id = "Conditional Access Policy"
|
||||
report.status_extended = (
|
||||
"Conditional Access Policy does not require MFA for management API."
|
||||
)
|
||||
|
||||
for policy_id, policy in conditional_access_policies.items():
|
||||
for policy in conditional_access_policies.values():
|
||||
if (
|
||||
policy.state == "enabled"
|
||||
and "All" in policy.users["include"]
|
||||
@@ -31,13 +22,24 @@ class entra_conditional_access_policy_require_mfa_for_management_api(Check):
|
||||
for access_control in policy.access_controls["grant"]
|
||||
)
|
||||
):
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_name}"
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
"Conditional Access Policy requires MFA for management API."
|
||||
)
|
||||
report.resource_id = policy_id
|
||||
report.resource_name = policy.name
|
||||
break
|
||||
else:
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.subscription = f"Tenant: {tenant_name}"
|
||||
report.resource_name = "Conditional Access Policy"
|
||||
report.resource_id = "Conditional Access Policy"
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"Conditional Access Policy does not require MFA for management API."
|
||||
)
|
||||
|
||||
findings.append(report)
|
||||
|
||||
|
||||
+3
-1
@@ -7,7 +7,9 @@ class entra_global_admin_in_less_than_five_users(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, directory_roles in entra_client.directory_roles.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=entra_client.users
|
||||
)
|
||||
report.status = "FAIL"
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = "Global Administrator"
|
||||
|
||||
+2
-4
@@ -14,11 +14,9 @@ class entra_non_privileged_user_has_mfa(Check):
|
||||
if not is_privileged_user(
|
||||
user, entra_client.directory_roles[tenant_domain]
|
||||
):
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(self.metadata(), resource_metadata=user)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = user_domain_name
|
||||
report.resource_id = user.id
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"Non-privileged user {user.name} does not have MFA."
|
||||
)
|
||||
|
||||
+4
-3
@@ -7,12 +7,13 @@ class entra_policy_default_users_cannot_create_security_groups(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Non-privileged users are able to create security groups via the Access Panel and the Azure administration portal."
|
||||
|
||||
if getattr(
|
||||
|
||||
+4
-3
@@ -7,12 +7,13 @@ class entra_policy_ensure_default_user_cannot_create_apps(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "App creation is not disabled for non-admin users."
|
||||
|
||||
if getattr(
|
||||
|
||||
+4
-2
@@ -7,11 +7,13 @@ class entra_policy_ensure_default_user_cannot_create_tenants(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
"Tenants creation is not disabled for non-admin users."
|
||||
)
|
||||
|
||||
+4
-2
@@ -7,11 +7,13 @@ class entra_policy_guest_invite_only_for_admin_roles(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Guest invitations are not restricted to users with specific administrative roles only."
|
||||
|
||||
if (
|
||||
|
||||
+4
-2
@@ -8,11 +8,13 @@ class entra_policy_guest_users_access_restrictions(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Guest user access is not restricted to properties and memberships of their own directory objects"
|
||||
|
||||
if (
|
||||
|
||||
+4
-2
@@ -7,11 +7,13 @@ class entra_policy_restricts_user_consent_for_apps(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Entra allows users to consent apps accessing company data on their behalf"
|
||||
|
||||
if getattr(auth_policy, "default_user_role_permissions", None) and not any(
|
||||
|
||||
+4
-2
@@ -7,11 +7,13 @@ class entra_policy_user_consent_for_verified_apps(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, auth_policy in entra_client.authorization_policy.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "PASS"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=auth_policy
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = getattr(auth_policy, "name", "Authorization Policy")
|
||||
report.resource_id = getattr(auth_policy, "id", "authorizationPolicy")
|
||||
report.status = "PASS"
|
||||
report.status_extended = "Entra does not allow users to consent non-verified apps accessing company data on their behalf."
|
||||
|
||||
if getattr(auth_policy, "default_user_role_permissions", None) and any(
|
||||
|
||||
+4
-4
@@ -14,11 +14,11 @@ class entra_privileged_user_has_mfa(Check):
|
||||
if is_privileged_user(
|
||||
user, entra_client.directory_roles[tenant_domain]
|
||||
):
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=user
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = user_domain_name
|
||||
report.resource_id = user.id
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"Privileged user {user.name} does not have MFA."
|
||||
)
|
||||
|
||||
+4
-4
@@ -10,11 +10,11 @@ class entra_security_defaults_enabled(Check):
|
||||
tenant,
|
||||
security_default,
|
||||
) in entra_client.security_default.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report.status = "FAIL"
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=security_default
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant}"
|
||||
report.resource_name = getattr(security_default, "name", "Security Default")
|
||||
report.resource_id = getattr(security_default, "id", "Security Default")
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Entra security defaults is diabled."
|
||||
|
||||
if getattr(security_default, "is_enabled", False):
|
||||
|
||||
@@ -176,6 +176,7 @@ class Entra(AzureService):
|
||||
named_locations[tenant].update(
|
||||
{
|
||||
named_location.id: NamedLocation(
|
||||
id=named_location.id,
|
||||
name=named_location.display_name,
|
||||
ip_ranges_addresses=[
|
||||
getattr(ip_range, "cidr_address", None)
|
||||
@@ -274,6 +275,7 @@ class Entra(AzureService):
|
||||
conditional_access_policy[tenant].update(
|
||||
{
|
||||
policy.id: ConditionalAccessPolicy(
|
||||
id=policy.id,
|
||||
name=policy.display_name,
|
||||
state=getattr(policy, "state", "None"),
|
||||
users={
|
||||
@@ -337,6 +339,7 @@ class SecurityDefault(BaseModel):
|
||||
|
||||
|
||||
class NamedLocation(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
ip_ranges_addresses: List[str]
|
||||
is_trusted: bool
|
||||
@@ -348,6 +351,7 @@ class DirectoryRole(BaseModel):
|
||||
|
||||
|
||||
class ConditionalAccessPolicy(BaseModel):
|
||||
id: str
|
||||
name: str
|
||||
state: str
|
||||
users: dict[str, List[str]]
|
||||
|
||||
+8
-5
@@ -7,7 +7,9 @@ class entra_trusted_named_locations_exists(Check):
|
||||
findings = []
|
||||
|
||||
for tenant, named_locations in entra_client.named_locations.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=named_locations
|
||||
)
|
||||
report.status = "FAIL"
|
||||
report.subscription = f"Tenant: {tenant}"
|
||||
report.resource_name = "Named Locations"
|
||||
@@ -15,11 +17,12 @@ class entra_trusted_named_locations_exists(Check):
|
||||
report.status_extended = (
|
||||
"There is no trusted location with IP ranges defined."
|
||||
)
|
||||
for named_location_id, named_location in named_locations.items():
|
||||
report.resource_name = named_location.name
|
||||
report.resource_id = named_location_id
|
||||
|
||||
for named_location in named_locations.values():
|
||||
if named_location.ip_ranges_addresses and named_location.is_trusted:
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=named_location
|
||||
)
|
||||
report.subscription = f"Tenant: {tenant}"
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Exits trusted location with trusted IP ranges, this IPs ranges are: {[ip_range for ip_range in named_location.ip_ranges_addresses if ip_range]}"
|
||||
break
|
||||
|
||||
+4
-5
@@ -37,13 +37,12 @@ class entra_user_with_vm_access_has_mfa(Check):
|
||||
]
|
||||
and assignment.agent_id == user.id
|
||||
):
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=user
|
||||
)
|
||||
report.subscription = subscription_name
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"User {user.name} without MFA can access VMs in subscription {subscription_name}"
|
||||
report.subscription = subscription_name
|
||||
report.resource_name = user_domain_name
|
||||
report.resource_id = user.id
|
||||
|
||||
if len(user.authentication_methods) > 1:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"User {user.name} can access VMs in subscription {subscription_name} but it has MFA."
|
||||
|
||||
+3
-1
@@ -7,7 +7,9 @@ class entra_users_cannot_create_microsoft_365_groups(Check):
|
||||
findings = []
|
||||
|
||||
for tenant_domain, group_settings in entra_client.group_settings.items():
|
||||
report = Check_Report_Azure(self.metadata())
|
||||
report = Check_Report_Azure(
|
||||
metadata=self.metadata(), resource_metadata=group_settings
|
||||
)
|
||||
report.status = "FAIL"
|
||||
report.subscription = f"Tenant: {tenant_domain}"
|
||||
report.resource_name = "Microsoft365 Groups"
|
||||
|
||||
+5
@@ -72,6 +72,7 @@ class Test_entra_conditional_access_policy_require_mfa_for_management_api:
|
||||
)
|
||||
|
||||
policy = ConditionalAccessPolicy(
|
||||
id=policy_id,
|
||||
name="Test Policy",
|
||||
state="enabled",
|
||||
users={"include": ["All"]},
|
||||
@@ -112,6 +113,7 @@ class Test_entra_conditional_access_policy_require_mfa_for_management_api:
|
||||
)
|
||||
|
||||
policy = ConditionalAccessPolicy(
|
||||
id=policy_id,
|
||||
name="Test Policy",
|
||||
state="enabled",
|
||||
users={"include": ["All"]},
|
||||
@@ -152,6 +154,7 @@ class Test_entra_conditional_access_policy_require_mfa_for_management_api:
|
||||
)
|
||||
|
||||
policy = ConditionalAccessPolicy(
|
||||
id=policy_id,
|
||||
name="Test Policy",
|
||||
state="disabled",
|
||||
users={"include": ["All"]},
|
||||
@@ -192,6 +195,7 @@ class Test_entra_conditional_access_policy_require_mfa_for_management_api:
|
||||
)
|
||||
|
||||
policy = ConditionalAccessPolicy(
|
||||
id=policy_id,
|
||||
name="Test Policy",
|
||||
state="enabled",
|
||||
users={"include": ["All"]},
|
||||
@@ -232,6 +236,7 @@ class Test_entra_conditional_access_policy_require_mfa_for_management_api:
|
||||
)
|
||||
|
||||
policy = ConditionalAccessPolicy(
|
||||
id=policy_id,
|
||||
name="Test Policy",
|
||||
state="enabled",
|
||||
users={"include": []},
|
||||
|
||||
+77
-30
@@ -8,12 +8,15 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
def test_entra_no_tenants(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users import (
|
||||
entra_global_admin_in_less_than_five_users,
|
||||
@@ -21,6 +24,8 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
|
||||
entra_client.directory_roles = {}
|
||||
|
||||
entra_client.uses = {}
|
||||
|
||||
check = entra_global_admin_in_less_than_five_users()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
@@ -28,12 +33,15 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
def test_entra_tenant_empty(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users import (
|
||||
entra_global_admin_in_less_than_five_users,
|
||||
@@ -41,6 +49,8 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
|
||||
entra_client.directory_roles = {DOMAIN: {}}
|
||||
|
||||
entra_client.users = {DOMAIN: {}}
|
||||
|
||||
check = entra_global_admin_in_less_than_five_users()
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
@@ -48,12 +58,15 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
def test_entra_less_than_five_global_admins(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users import (
|
||||
entra_global_admin_in_less_than_five_users,
|
||||
@@ -79,6 +92,13 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
}
|
||||
}
|
||||
|
||||
entra_client.users = {
|
||||
DOMAIN: {
|
||||
f"User1@{DOMAIN}": User(id=id_user1, name="User1"),
|
||||
f"User2@{DOMAIN}": User(id=id_user2, name="User2"),
|
||||
}
|
||||
}
|
||||
|
||||
check = entra_global_admin_in_less_than_five_users()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
@@ -91,12 +111,15 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
def test_entra_more_than_five_global_admins(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users import (
|
||||
entra_global_admin_in_less_than_five_users,
|
||||
@@ -130,6 +153,17 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
}
|
||||
}
|
||||
|
||||
entra_client.users = {
|
||||
DOMAIN: {
|
||||
f"User1@{DOMAIN}": User(id=id_user1, name="User1"),
|
||||
f"User2@{DOMAIN}": User(id=id_user2, name="User2"),
|
||||
f"User3@{DOMAIN}": User(id=id_user3, name="User3"),
|
||||
f"User4@{DOMAIN}": User(id=id_user4, name="User4"),
|
||||
f"User5@{DOMAIN}": User(id=id_user5, name="User5"),
|
||||
f"User6@{DOMAIN}": User(id=id_user6, name="User6"),
|
||||
}
|
||||
}
|
||||
|
||||
check = entra_global_admin_in_less_than_five_users()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
@@ -145,12 +179,15 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
def test_entra_exactly_five_global_admins(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_global_admin_in_less_than_five_users.entra_global_admin_in_less_than_five_users import (
|
||||
entra_global_admin_in_less_than_five_users,
|
||||
@@ -182,6 +219,16 @@ class Test_entra_global_admin_in_less_than_five_users:
|
||||
}
|
||||
}
|
||||
|
||||
entra_client.users = {
|
||||
DOMAIN: {
|
||||
f"User1@{DOMAIN}": User(id=id_user1, name="User1"),
|
||||
f"User2@{DOMAIN}": User(id=id_user2, name="User2"),
|
||||
f"User3@{DOMAIN}": User(id=id_user3, name="User3"),
|
||||
f"User4@{DOMAIN}": User(id=id_user4, name="User4"),
|
||||
f"User5@{DOMAIN}": User(id=id_user5, name="User5"),
|
||||
}
|
||||
}
|
||||
|
||||
check = entra_global_admin_in_less_than_five_users()
|
||||
result = check.execute()
|
||||
assert len(result) == 1
|
||||
|
||||
+2
-2
@@ -81,7 +81,7 @@ class Test_entra_non_privileged_user_has_mfa:
|
||||
result[0].status_extended
|
||||
== "Non-privileged user foo does not have MFA."
|
||||
)
|
||||
assert result[0].resource_name == f"foo@{DOMAIN}"
|
||||
assert result[0].resource_name == "foo"
|
||||
assert result[0].resource_id == user_id
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
|
||||
@@ -118,7 +118,7 @@ class Test_entra_non_privileged_user_has_mfa:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == "Non-privileged user foo has MFA."
|
||||
assert result[0].resource_name == f"foo@{DOMAIN}"
|
||||
assert result[0].resource_name == "foo"
|
||||
assert result[0].resource_id == user_id
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
|
||||
|
||||
+2
-2
@@ -144,7 +144,7 @@ class Test_entra_privileged_user_has_mfa:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == "Privileged user foo does not have MFA."
|
||||
assert result[0].resource_name == f"foo@{DOMAIN}"
|
||||
assert result[0].resource_name == "foo"
|
||||
assert result[0].resource_id == user_id
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
|
||||
@@ -183,6 +183,6 @@ class Test_entra_privileged_user_has_mfa:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].status_extended == "Privileged user foo has MFA."
|
||||
assert result[0].resource_name == f"foo@{DOMAIN}"
|
||||
assert result[0].resource_name == "foo"
|
||||
assert result[0].resource_id == user_id
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ class Test_entra_security_defaults_enabled:
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].status_extended == "Entra security defaults is diabled."
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
assert result[0].resource_name == "Security Default"
|
||||
assert result[0].resource_id == "Security Default"
|
||||
assert result[0].resource_name == ""
|
||||
assert result[0].resource_id == ""
|
||||
|
||||
def test_entra_security_default_enabled(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
@@ -61,6 +61,7 @@ async def mock_entra_get_named_locations(_):
|
||||
return {
|
||||
DOMAIN: {
|
||||
"id-1": NamedLocation(
|
||||
id="id-1",
|
||||
name="Test",
|
||||
ip_ranges_addresses=[],
|
||||
is_trusted=False,
|
||||
|
||||
+55
-35
@@ -7,12 +7,15 @@ class Test_entra_trusted_named_locations_exists:
|
||||
def test_entra_no_tenants(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists import (
|
||||
entra_trusted_named_locations_exists,
|
||||
@@ -27,12 +30,15 @@ class Test_entra_trusted_named_locations_exists:
|
||||
def test_entra_tenant_empty(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists import (
|
||||
entra_trusted_named_locations_exists,
|
||||
@@ -55,12 +61,15 @@ class Test_entra_trusted_named_locations_exists:
|
||||
def test_entra_named_location_with_ip_ranges(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_service import (
|
||||
NamedLocation,
|
||||
@@ -72,6 +81,7 @@ class Test_entra_trusted_named_locations_exists:
|
||||
entra_client.named_locations = {
|
||||
DOMAIN: {
|
||||
"location_id": NamedLocation(
|
||||
id="location_id",
|
||||
name="Test Location",
|
||||
ip_ranges_addresses=["192.168.0.1/24"],
|
||||
is_trusted=True,
|
||||
@@ -94,12 +104,15 @@ class Test_entra_trusted_named_locations_exists:
|
||||
def test_entra_named_location_without_ip_ranges(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_service import (
|
||||
NamedLocation,
|
||||
@@ -111,7 +124,10 @@ class Test_entra_trusted_named_locations_exists:
|
||||
entra_client.named_locations = {
|
||||
DOMAIN: {
|
||||
"location_id": NamedLocation(
|
||||
name="Test Location", ip_ranges_addresses=[], is_trusted=True
|
||||
id="location_id",
|
||||
name="Test Location",
|
||||
ip_ranges_addresses=[],
|
||||
is_trusted=True,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -125,18 +141,21 @@ class Test_entra_trusted_named_locations_exists:
|
||||
== "There is no trusted location with IP ranges defined."
|
||||
)
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
assert result[0].resource_name == "Test Location"
|
||||
assert result[0].resource_id == "location_id"
|
||||
assert result[0].resource_name == "Named Locations"
|
||||
assert result[0].resource_id == "Named Locations"
|
||||
|
||||
def test_entra_new_named_location_with_ip_ranges_not_trusted(self):
|
||||
entra_client = mock.MagicMock
|
||||
|
||||
with mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
), mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
with (
|
||||
mock.patch(
|
||||
"prowler.providers.common.provider.Provider.get_global_provider",
|
||||
return_value=set_mocked_azure_provider(),
|
||||
),
|
||||
mock.patch(
|
||||
"prowler.providers.azure.services.entra.entra_trusted_named_locations_exists.entra_trusted_named_locations_exists.entra_client",
|
||||
new=entra_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.azure.services.entra.entra_service import (
|
||||
NamedLocation,
|
||||
@@ -148,6 +167,7 @@ class Test_entra_trusted_named_locations_exists:
|
||||
entra_client.named_locations = {
|
||||
DOMAIN: {
|
||||
"location_id": NamedLocation(
|
||||
id="location_id",
|
||||
name="Test Location",
|
||||
ip_ranges_addresses=["192.168.0.1/24"],
|
||||
is_trusted=False,
|
||||
@@ -164,5 +184,5 @@ class Test_entra_trusted_named_locations_exists:
|
||||
== "There is no trusted location with IP ranges defined."
|
||||
)
|
||||
assert result[0].subscription == f"Tenant: {DOMAIN}"
|
||||
assert result[0].resource_name == "Test Location"
|
||||
assert result[0].resource_id == "location_id"
|
||||
assert result[0].resource_name == "Named Locations"
|
||||
assert result[0].resource_id == "Named Locations"
|
||||
|
||||
+2
-2
@@ -92,7 +92,7 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
== f"User test can access VMs in subscription {AZURE_SUBSCRIPTION_ID} but it has MFA."
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == f"test@{DOMAIN}"
|
||||
assert result[0].resource_name == "test"
|
||||
assert result[0].resource_id == user_id
|
||||
|
||||
def test_entra_user_with_vm_access_has_mfa_no_mfa(self):
|
||||
@@ -150,7 +150,7 @@ class Test_iam_assignment_priviledge_access_vm_has_mfa:
|
||||
== f"User test without MFA can access VMs in subscription {AZURE_SUBSCRIPTION_ID}"
|
||||
)
|
||||
assert result[0].subscription == AZURE_SUBSCRIPTION_ID
|
||||
assert result[0].resource_name == f"test@{DOMAIN}"
|
||||
assert result[0].resource_name == "test"
|
||||
assert result[0].resource_id == user_id
|
||||
|
||||
def test_entra_user_with_vm_access_has_mfa_no_user(self):
|
||||
|
||||
Reference in New Issue
Block a user