From b8ce09ec34055783d406ebadf4059b698b3bfd4e Mon Sep 17 00:00:00 2001 From: Hugo Pereira Brito <101209179+HugoPBrito@users.noreply.github.com> Date: Mon, 31 Mar 2025 17:50:51 +0200 Subject: [PATCH] fix(entra): check name and logic of `entra_admin_users_have_mfa_enabled` (#7230) --- .../__init__.py | 0 ..._portals_access_restriction.metadata.json} | 5 +- ...entra_admin_portals_access_restriction.py} | 2 +- .../__init__.py | 0 ...tra_admin_users_mfa_enabled.metadata.json} | 5 +- .../entra_admin_users_mfa_enabled.py} | 10 +- ..._admin_portals_access_restriction_test.py} | 34 +-- .../entra_admin_users_mfa_enabled_test.py} | 205 +++++++++++++++--- 8 files changed, 207 insertions(+), 54 deletions(-) rename prowler/providers/microsoft365/services/entra/{entra_admin_mfa_enabled_for_administrative_roles => entra_admin_portals_access_restriction}/__init__.py (100%) rename prowler/providers/microsoft365/services/entra/{entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.metadata.json => entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.metadata.json} (94%) rename prowler/providers/microsoft365/services/entra/{entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.py => entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.py} (98%) rename prowler/providers/microsoft365/services/entra/{entra_admin_portals_role_limited_access => entra_admin_users_mfa_enabled}/__init__.py (100%) rename prowler/providers/microsoft365/services/entra/{entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.metadata.json => entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.metadata.json} (93%) rename prowler/providers/microsoft365/services/entra/{entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.py => entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.py} (91%) rename tests/providers/microsoft365/services/entra/{entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access_test.py => entra_admin_portals_access_restriction/entra_admin_portals_access_restriction_test.py} (89%) rename tests/providers/microsoft365/services/entra/{entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles_test.py => entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled_test.py} (71%) diff --git a/prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/__init__.py b/prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/__init__.py similarity index 100% rename from prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/__init__.py rename to prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/__init__.py diff --git a/prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.metadata.json b/prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.metadata.json similarity index 94% rename from prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.metadata.json rename to prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.metadata.json index 87493e9bd0..41ba6ba9ce 100644 --- a/prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.metadata.json +++ b/prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.metadata.json @@ -1,7 +1,10 @@ { "Provider": "microsoft365", - "CheckID": "entra_admin_portals_role_limited_access", + "CheckID": "entra_admin_portals_access_restriction", "CheckTitle": "Ensure that only administrative roles have access to Microsoft Admin Portals", + "CheckAliases": [ + "entra_admin_portals_role_limited_access" + ], "CheckType": [], "ServiceName": "entra", "SubServiceName": "", diff --git a/prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.py b/prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.py similarity index 98% rename from prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.py rename to prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.py index 0b0b08aaac..a8f744ec4a 100644 --- a/prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access.py +++ b/prowler/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction.py @@ -7,7 +7,7 @@ from prowler.providers.microsoft365.services.entra.entra_service import ( ) -class entra_admin_portals_role_limited_access(Check): +class entra_admin_portals_access_restriction(Check): """Check if Conditional Access policies deny access to the Microsoft 365 admin center for users with limited access roles. This check ensures that Conditional Access policies are in place to deny access to the Microsoft 365 admin center for users with limited access roles. diff --git a/prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/__init__.py b/prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/__init__.py similarity index 100% rename from prowler/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/__init__.py rename to prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/__init__.py diff --git a/prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.metadata.json b/prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.metadata.json similarity index 93% rename from prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.metadata.json rename to prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.metadata.json index 942e1a3c97..63f312be10 100644 --- a/prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.metadata.json +++ b/prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.metadata.json @@ -1,7 +1,10 @@ { "Provider": "microsoft365", - "CheckID": "entra_admin_mfa_enabled_for_administrative_roles", + "CheckID": "entra_admin_users_mfa_enabled", "CheckTitle": "Ensure multifactor authentication is enabled for all users in administrative roles.", + "CheckAliases": [ + "entra_admin_mfa_enabled_for_administrative_roles" + ], "CheckType": [], "ServiceName": "entra", "SubServiceName": "", diff --git a/prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.py b/prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.py similarity index 91% rename from prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.py rename to prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.py index d69276f135..e668ffd11a 100644 --- a/prowler/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles.py +++ b/prowler/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled.py @@ -9,7 +9,7 @@ from prowler.providers.microsoft365.services.entra.entra_service import ( ) -class entra_admin_mfa_enabled_for_administrative_roles(Check): +class entra_admin_users_mfa_enabled(Check): """ Ensure multifactor authentication is enabled for all users in administrative roles. @@ -68,13 +68,13 @@ class entra_admin_mfa_enabled_for_administrative_roles(Check): resource_name=policy.display_name, resource_id=policy.id, ) - report.status = "PASS" - report.status_extended = f"Conditional Access Policy '{policy.display_name}' enforces MFA for administrative roles." - if policy.state == ConditionalAccessPolicyState.ENABLED_FOR_REPORTING: report.status = "FAIL" report.status_extended = f"Conditional Access Policy '{policy.display_name}' only reports MFA for administrative roles but does not enforce it." - break + else: + report.status = "PASS" + report.status_extended = f"Conditional Access Policy '{policy.display_name}' enforces MFA for administrative roles." + break findings.append(report) return findings diff --git a/tests/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access_test.py b/tests/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction_test.py similarity index 89% rename from tests/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access_test.py rename to tests/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction_test.py index 71eaaa4dd4..23bed663b9 100644 --- a/tests/providers/microsoft365/services/entra/entra_admin_portals_role_limited_access/entra_admin_portals_role_limited_access_test.py +++ b/tests/providers/microsoft365/services/entra/entra_admin_portals_access_restriction/entra_admin_portals_access_restriction_test.py @@ -20,7 +20,7 @@ from tests.providers.microsoft365.microsoft365_fixtures import ( ) -class Test_entra_admin_portals_role_limited_access: +class Test_entra_admin_portals_access_restriction: def test_entra_no_conditional_access_policies(self): entra_client = mock.MagicMock entra_client.audited_tenant = "audited_tenant" @@ -31,17 +31,17 @@ class Test_entra_admin_portals_role_limited_access: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access import ( - entra_admin_portals_role_limited_access, + from prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction import ( + entra_admin_portals_access_restriction, ) entra_client.conditional_access_policies = {} - check = entra_admin_portals_role_limited_access() + check = entra_admin_portals_access_restriction() result = check.execute() assert len(result) == 1 assert result[0].status == "FAIL" @@ -66,12 +66,12 @@ class Test_entra_admin_portals_role_limited_access: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access import ( - entra_admin_portals_role_limited_access, + from prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction import ( + entra_admin_portals_access_restriction, ) from prowler.providers.microsoft365.services.entra.entra_service import ( ConditionalAccessPolicy, @@ -114,7 +114,7 @@ class Test_entra_admin_portals_role_limited_access: ) } - check = entra_admin_portals_role_limited_access() + check = entra_admin_portals_access_restriction() result = check.execute() assert len(result) == 1 assert result[0].status == "FAIL" @@ -140,12 +140,12 @@ class Test_entra_admin_portals_role_limited_access: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access import ( - entra_admin_portals_role_limited_access, + from prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction import ( + entra_admin_portals_access_restriction, ) from prowler.providers.microsoft365.services.entra.entra_service import ( ConditionalAccessPolicy, @@ -189,7 +189,7 @@ class Test_entra_admin_portals_role_limited_access: ) } - check = entra_admin_portals_role_limited_access() + check = entra_admin_portals_access_restriction() result = check.execute() assert len(result) == 1 assert result[0].status == "FAIL" @@ -218,12 +218,12 @@ class Test_entra_admin_portals_role_limited_access: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_portals_role_limited_access.entra_admin_portals_role_limited_access import ( - entra_admin_portals_role_limited_access, + from prowler.providers.microsoft365.services.entra.entra_admin_portals_access_restriction.entra_admin_portals_access_restriction import ( + entra_admin_portals_access_restriction, ) from prowler.providers.microsoft365.services.entra.entra_service import ( ConditionalAccessPolicy, @@ -267,7 +267,7 @@ class Test_entra_admin_portals_role_limited_access: ) } - check = entra_admin_portals_role_limited_access() + check = entra_admin_portals_access_restriction() result = check.execute() assert len(result) == 1 assert result[0].status == "PASS" diff --git a/tests/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles_test.py b/tests/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled_test.py similarity index 71% rename from tests/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles_test.py rename to tests/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled_test.py index 4492ac809c..1a628de808 100644 --- a/tests/providers/microsoft365/services/entra/entra_admin_mfa_enabled_for_administrative_roles/entra_admin_mfa_enabled_for_administrative_roles_test.py +++ b/tests/providers/microsoft365/services/entra/entra_admin_users_mfa_enabled/entra_admin_users_mfa_enabled_test.py @@ -21,7 +21,7 @@ from tests.providers.microsoft365.microsoft365_fixtures import ( ) -class Test_entra_admin_mfa_enabled_for_administrative_roles: +class Test_entra_admin_users_mfa_enabled: def test_no_conditional_access_policies(self): """No conditional access policies configured: expected FAIL.""" entra_client = mock.MagicMock @@ -34,17 +34,17 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = {} - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -70,12 +70,12 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = { @@ -116,7 +116,7 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: ) } - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -146,12 +146,12 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = { @@ -192,7 +192,7 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: ) } - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -222,12 +222,12 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = { @@ -268,7 +268,7 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: ) } - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -303,12 +303,12 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = { @@ -349,7 +349,7 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: ) } - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -382,12 +382,12 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = { @@ -444,7 +444,7 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: ) } - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -477,12 +477,12 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: return_value=set_mocked_microsoft365_provider(), ), mock.patch( - "prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles.entra_client", + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", new=entra_client, ), ): - from prowler.providers.microsoft365.services.entra.entra_admin_mfa_enabled_for_administrative_roles.entra_admin_mfa_enabled_for_administrative_roles import ( - entra_admin_mfa_enabled_for_administrative_roles, + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, ) entra_client.conditional_access_policies = { @@ -538,7 +538,7 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: ) } - check = entra_admin_mfa_enabled_for_administrative_roles() + check = entra_admin_users_mfa_enabled() result = check.execute() assert len(result) == 1 @@ -548,3 +548,150 @@ class Test_entra_admin_mfa_enabled_for_administrative_roles: assert result[0].resource == {} assert result[0].resource_name == "Conditional Access Policies" assert result[0].resource_id == "conditionalAccessPolicies" + + def test_policy_invalid_and_valid_policy(self): + """ + Valid policy: + - State enabled (ENABLED) + - Applies to administrative roles + - Application conditions include "All" + - MFA is configured in grant_controls + + Expected PASS. + """ + policy_id = str(uuid4()) + policy_id2 = str(uuid4()) + display_name = "Valid MFA Policy" + entra_client = mock.MagicMock + entra_client.audited_tenant = "audited_tenant" + entra_client.audited_domain = DOMAIN + + with ( + mock.patch( + "prowler.providers.common.provider.Provider.get_global_provider", + return_value=set_mocked_microsoft365_provider(), + ), + mock.patch( + "prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled.entra_client", + new=entra_client, + ), + ): + from prowler.providers.microsoft365.services.entra.entra_admin_users_mfa_enabled.entra_admin_users_mfa_enabled import ( + entra_admin_users_mfa_enabled, + ) + + entra_client.conditional_access_policies = { + policy_id: ConditionalAccessPolicy( + id=policy_id, + display_name=display_name, + conditions=Conditions( + application_conditions=ApplicationsConditions( + included_applications=["All"], + excluded_applications=[], + included_user_actions=[], + ), + user_conditions=UsersConditions( + included_groups=[], + excluded_groups=[], + included_users=[], + excluded_users=[], + included_roles=[ + "9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3", + "c4e39bd9-1100-46d3-8c65-fb160da0071f", + "b0f54661-2d74-4c50-afa3-1ec803f12efe", + "158c047a-c907-4556-b7ef-446551a6b5f7", + "b1be1c3e-b65d-4f19-8427-f6fa0d97feb9", + "29232cdf-9323-42fd-ade2-1d097af3e4de", + "62e90394-69f5-4237-9190-012177145e10", + "f2ef992c-3afb-46b9-b7cf-a126ee74c451", + "729827e3-9c14-49f7-bb1b-9608f156bbb8", + "966707d0-3269-4727-9be2-8c3a10f19b9d", + "7be44c8a-adaf-4e2a-84d6-ab2649e08a13", + "e8611ab8-c189-46e8-94e1-60213ab1f814", + "194ae4cb-b126-40b2-bd5b-6091b380977d", + "f28a1f50-f6e7-4571-818b-6a12f2af6b6c", + "fe930be7-5e62-47db-91af-98c3a49a38b1", + ], + excluded_roles=[], + ), + ), + grant_controls=GrantControls( + built_in_controls=[ConditionalAccessGrantControl.MFA], + operator=GrantControlOperator.AND, + ), + session_controls=SessionControls( + persistent_browser=PersistentBrowser( + is_enabled=False, mode="always" + ), + sign_in_frequency=SignInFrequency( + is_enabled=False, + frequency=None, + type=None, + interval=SignInFrequencyInterval.EVERY_TIME, + ), + ), + state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING, + ), + policy_id2: ConditionalAccessPolicy( + id=policy_id, + display_name=display_name, + conditions=Conditions( + application_conditions=ApplicationsConditions( + included_applications=["All"], + excluded_applications=[], + included_user_actions=[], + ), + user_conditions=UsersConditions( + included_groups=[], + excluded_groups=[], + included_users=[], + excluded_users=[], + included_roles=[ + "9b895d92-2cd3-44c7-9d02-a6ac2d5ea5c3", + "c4e39bd9-1100-46d3-8c65-fb160da0071f", + "b0f54661-2d74-4c50-afa3-1ec803f12efe", + "158c047a-c907-4556-b7ef-446551a6b5f7", + "b1be1c3e-b65d-4f19-8427-f6fa0d97feb9", + "29232cdf-9323-42fd-ade2-1d097af3e4de", + "62e90394-69f5-4237-9190-012177145e10", + "f2ef992c-3afb-46b9-b7cf-a126ee74c451", + "729827e3-9c14-49f7-bb1b-9608f156bbb8", + "966707d0-3269-4727-9be2-8c3a10f19b9d", + "7be44c8a-adaf-4e2a-84d6-ab2649e08a13", + "e8611ab8-c189-46e8-94e1-60213ab1f814", + "194ae4cb-b126-40b2-bd5b-6091b380977d", + "f28a1f50-f6e7-4571-818b-6a12f2af6b6c", + "fe930be7-5e62-47db-91af-98c3a49a38b1", + ], + excluded_roles=[], + ), + ), + grant_controls=GrantControls( + built_in_controls=[ConditionalAccessGrantControl.MFA], + operator=GrantControlOperator.AND, + ), + session_controls=SessionControls( + persistent_browser=PersistentBrowser( + is_enabled=False, mode="always" + ), + sign_in_frequency=SignInFrequency( + is_enabled=False, + frequency=None, + type=None, + interval=SignInFrequencyInterval.EVERY_TIME, + ), + ), + state=ConditionalAccessPolicyState.ENABLED, + ), + } + + check = entra_admin_users_mfa_enabled() + result = check.execute() + + assert len(result) == 1 + assert result[0].status == "PASS" + expected_status_extended = f"Conditional Access Policy '{display_name}' enforces MFA for administrative roles." + assert result[0].status_extended == expected_status_extended + assert result[0].resource == entra_client.conditional_access_policies + assert result[0].resource_name == display_name + assert result[0].resource_id == policy_id