feat(entra): extract Entra resource metadata automated (#6542)

Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
This commit is contained in:
Rubén De la Torre Vico
2025-01-16 16:24:53 +01:00
committed by Pepe Fagoaga
parent b0807478f2
commit 9b0dd80f13
24 changed files with 220 additions and 125 deletions
@@ -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)
@@ -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"
@@ -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."
)
@@ -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(
@@ -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(
@@ -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."
)
@@ -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 (
@@ -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 (
@@ -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(
@@ -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(
@@ -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."
)
@@ -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]]
@@ -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
@@ -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."
@@ -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"
@@ -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": []},
@@ -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
@@ -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}"
@@ -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}"
@@ -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,
@@ -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"
@@ -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):