Skip to content

Commit 361f854

Browse files
feat(azure): add 'entra_conditional_access_policy_require_mfa_for_admin_portals' check and update compliance (#10330)
1 parent 2b7b262 commit 361f854

File tree

11 files changed

+379
-9
lines changed

11 files changed

+379
-9
lines changed

prowler/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
88

99
- `entra_conditional_access_policy_device_code_flow_blocked` check for M365 provider [(#10218)](https://github.com/prowler-cloud/prowler/pull/10218)
1010
- CheckMetadata Pydantic validators [(#8584)](https://github.com/prowler-cloud/prowler/pull/8583)
11+
- `entra_conditional_access_policy_require_mfa_for_admin_portals` check for Azure provider and update CIS compliance [(#10330)](https://github.com/prowler-cloud/prowler/pull/10330)
1112

1213
### 🔄 Changed
1314

prowler/compliance/azure/cis_3.0_azure.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,7 @@
752752
"Id": "2.2.8",
753753
"Description": "Ensure Multi-factor Authentication is Required to access Microsoft Admin Portals",
754754
"Checks": [
755-
"defender_ensure_defender_for_server_is_on"
755+
"entra_conditional_access_policy_require_mfa_for_admin_portals"
756756
],
757757
"Attributes": [
758758
{

prowler/compliance/azure/cis_4.0_azure.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1036,7 +1036,7 @@
10361036
"Id": "6.2.7",
10371037
"Description": "Ensure that multifactor authentication is required to access Microsoft Admin Portals",
10381038
"Checks": [
1039-
"defender_ensure_defender_for_server_is_on"
1039+
"entra_conditional_access_policy_require_mfa_for_admin_portals"
10401040
],
10411041
"Attributes": [
10421042
{

prowler/compliance/azure/cis_5.0_azure.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@
472472
"Id": "5.2.7",
473473
"Description": "Ensure that multifactor authentication is required to access Microsoft Admin Portals",
474474
"Checks": [
475-
"defender_ensure_defender_for_server_is_on"
475+
"entra_conditional_access_policy_require_mfa_for_admin_portals"
476476
],
477477
"Attributes": [
478478
{

prowler/compliance/azure/prowler_threatscore_azure.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
"Id": "1.1.4",
6464
"Description": "Ensure Multi-factor Authentication is Required to access Microsoft Admin Portals",
6565
"Checks": [
66-
"defender_ensure_defender_for_server_is_on"
66+
"entra_conditional_access_policy_require_mfa_for_admin_portals"
6767
],
6868
"Attributes": [
6969
{

prowler/providers/azure/config.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from uuid import UUID
22

3-
# Service management API
3+
# Conditional Access target resource identifiers
4+
# (Graph API includeApplications values)
45
WINDOWS_AZURE_SERVICE_MANAGEMENT_API = "797f4846-ba00-4fd7-ba43-dac1f8f63013"
6+
# Named app group — Graph API returns this literal string, not a GUID
7+
MICROSOFT_ADMIN_PORTALS = "MicrosoftAdminPortals"
58

69
# Authorization policy roles
710
GUEST_USER_ACCESS_NO_RESTRICTICTED = UUID("a0b1b346-4d3e-4e8b-98f8-753987be4970")

prowler/providers/azure/services/entra/entra_conditional_access_policy_require_mfa_for_admin_portals/__init__.py

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"Provider": "azure",
3+
"CheckID": "entra_conditional_access_policy_require_mfa_for_admin_portals",
4+
"CheckTitle": "Conditional Access policy requires MFA for Microsoft Admin Portals",
5+
"CheckType": [],
6+
"ServiceName": "entra",
7+
"SubServiceName": "",
8+
"ResourceIdTemplate": "",
9+
"Severity": "medium",
10+
"ResourceType": "NotDefined",
11+
"ResourceGroup": "IAM",
12+
"Description": "**Microsoft Entra Conditional Access** is evaluated for a policy that requires **multifactor authentication** when accessing **Microsoft Admin Portals** (Microsoft 365 Admin Center, Microsoft Entra Admin Center, Microsoft Exchange Admin Center, etc.). The check confirms an enabled policy targets **All users**, includes the Microsoft Admin Portals app, and enforces an **MFA** grant control.",
13+
"Risk": "Without **MFA** on admin portals, attackers with stolen credentials can access **Microsoft 365 Admin Center**, **Entra Admin Center**, or **Exchange Admin Center** to modify tenant settings, escalate privileges, and exfiltrate data. This directly impacts **confidentiality**, **integrity**, and **availability** of all services managed through those portals.",
14+
"RelatedUrl": "",
15+
"AdditionalURLs": [
16+
"https://learn.microsoft.com/en-us/entra/identity/conditional-access/how-to-policy-mfa-admin-portals",
17+
"https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-cloud-apps"
18+
],
19+
"Remediation": {
20+
"Code": {
21+
"CLI": "",
22+
"NativeIaC": "",
23+
"Other": "1. Sign in to the Microsoft Entra admin center\n2. Go to Protection > Conditional Access > Policies\n3. Click + New policy and enter a name\n4. Under Users > Include, select All users\n5. Under Exclude, check Users and groups and select break-glass / non-interactive service accounts\n6. Under Target resources > Include, click Select apps, then select Microsoft Admin Portals\n7. Under Grant, select Grant access and check Require multifactor authentication\n8. Set Enable policy to Report-only, click Create\n9. After testing, change Enable policy from Report-only to On",
24+
"Terraform": "```hcl\nresource \"azuread_conditional_access_policy\" \"<example_resource_name>\" {\n display_name = \"<example_resource_name>\"\n state = \"enabled\"\n\n conditions {\n users {\n included_users = [\"All\"]\n excluded_users = [\"<break_glass_account_id>\"]\n }\n applications {\n included_applications = [\"MicrosoftAdminPortals\"] # Critical: Microsoft Admin Portals\n }\n }\n\n grant_controls {\n operator = \"OR\"\n built_in_controls = [\"mfa\"] # Critical: requires MFA\n }\n}\n```"
25+
},
26+
"Recommendation": {
27+
"Text": "Create a **Conditional Access policy** that requires **MFA** for the **Microsoft Admin Portals** app targeting **All users**. Exclude only **break-glass** emergency accounts and non-interactive service principals. Test in **Report-only** mode before enforcing. Prefer **phishing-resistant** MFA methods (FIDO2, passkeys) and apply **least privilege** principles.",
28+
"Url": "https://hub.prowler.com/check/entra_conditional_access_policy_require_mfa_for_admin_portals"
29+
}
30+
},
31+
"Categories": [
32+
"identity-access",
33+
"e3"
34+
],
35+
"DependsOn": [],
36+
"RelatedTo": [],
37+
"Notes": "Conditional Access policies require Microsoft Entra ID P1 or P2 licenses. Similarly, they may require additional overhead to maintain if users lose access to their MFA. Any users or groups which are granted an exception to this policy should be carefully tracked, be granted only minimal necessary privileges, and conditional access exceptions should be regularly reviewed or investigated."
38+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from prowler.lib.check.models import Check, Check_Report_Azure
2+
from prowler.providers.azure.config import MICROSOFT_ADMIN_PORTALS
3+
from prowler.providers.azure.services.entra.entra_client import entra_client
4+
5+
6+
class entra_conditional_access_policy_require_mfa_for_admin_portals(Check):
7+
def execute(self) -> Check_Report_Azure:
8+
findings = []
9+
10+
for (
11+
tenant_name,
12+
conditional_access_policies,
13+
) in entra_client.conditional_access_policy.items():
14+
for policy in conditional_access_policies.values():
15+
if (
16+
policy.state == "enabled"
17+
and "All" in policy.users["include"]
18+
and MICROSOFT_ADMIN_PORTALS in policy.target_resources["include"]
19+
and any(
20+
"mfa" in access_control.lower()
21+
for access_control in policy.access_controls["grant"]
22+
)
23+
):
24+
report = Check_Report_Azure(
25+
metadata=self.metadata(), resource=policy
26+
)
27+
report.subscription = f"Tenant: {tenant_name}"
28+
report.status = "PASS"
29+
report.status_extended = "Conditional Access Policy requires MFA for Microsoft Admin Portals."
30+
break
31+
else:
32+
report = Check_Report_Azure(
33+
metadata=self.metadata(),
34+
resource=conditional_access_policies,
35+
)
36+
report.subscription = f"Tenant: {tenant_name}"
37+
report.resource_name = "Conditional Access Policy"
38+
report.resource_id = "Conditional Access Policy"
39+
report.status = "FAIL"
40+
report.status_extended = "Conditional Access Policy does not require MFA for Microsoft Admin Portals."
41+
42+
findings.append(report)
43+
44+
return findings

prowler/providers/azure/services/entra/entra_conditional_access_policy_require_mfa_for_management_api/entra_conditional_access_policy_require_mfa_for_management_api.metadata.json

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@
99
"Severity": "medium",
1010
"ResourceType": "NotDefined",
1111
"ResourceGroup": "IAM",
12-
"Description": "This recommendation ensures that users accessing the Windows Azure Service Management API (i.e. Azure Powershell, Azure CLI, Azure Resource Manager API, etc.) are required to use multifactor authentication (MFA) credentials when accessing resources through the Windows Azure Service Management API.",
13-
"Risk": "Administrative access to the Windows Azure Service Management API should be secured with a higher level of scrutiny to authenticating mechanisms. Enabling multifactor authentication is recommended to reduce the potential for abuse of Administrative actions, and to prevent intruders or compromised admin credentials from changing administrative settings.",
12+
"Description": "**Microsoft Entra Conditional Access** is evaluated for a policy that requires **multifactor authentication** when accessing the **Windows Azure Service Management API** (Azure PowerShell, Azure CLI, Azure Resource Manager API, etc.). The check confirms an enabled policy targets **All users**, includes the Service Management API app, and enforces an **MFA** grant control.",
13+
"Risk": "Without **MFA** on the Service Management API, attackers with stolen credentials can use **Azure CLI**, **PowerShell**, or the **Resource Manager API** to modify infrastructure, escalate privileges, and exfiltrate data. This directly impacts **confidentiality**, **integrity**, and **availability** of all Azure resources managed through the API.",
1414
"RelatedUrl": "",
15+
"AdditionalURLs": [
16+
"https://learn.microsoft.com/en-us/entra/identity/conditional-access/howto-conditional-access-policy-azure-management",
17+
"https://learn.microsoft.com/en-us/entra/identity/conditional-access/concept-conditional-access-cloud-apps"
18+
],
1519
"Remediation": {
1620
"Code": {
1721
"CLI": "",
1822
"NativeIaC": "",
19-
"Other": "",
20-
"Terraform": ""
23+
"Other": "1. Sign in to the Microsoft Entra admin center\n2. Go to Protection > Conditional Access > Policies\n3. Click + New policy and enter a name\n4. Under Users > Include, select All users\n5. Under Exclude, check Users and groups and select break-glass / non-interactive service accounts\n6. Under Target resources > Include, click Select apps, then select Windows Azure Service Management API\n7. Under Grant, select Grant access and check Require multifactor authentication\n8. Set Enable policy to Report-only, click Create\n9. After testing, change Enable policy from Report-only to On",
24+
"Terraform": "```hcl\nresource \"azuread_conditional_access_policy\" \"<example_resource_name>\" {\n display_name = \"<example_resource_name>\"\n state = \"enabled\"\n\n conditions {\n users {\n included_users = [\"All\"]\n excluded_users = [\"<break_glass_account_id>\"]\n }\n applications {\n included_applications = [\"797f4846-ba00-4fd7-ba43-dac1f8f63013\"] # Critical: Windows Azure Service Management API\n }\n }\n\n grant_controls {\n operator = \"OR\"\n built_in_controls = [\"mfa\"] # Critical: requires MFA\n }\n}\n```"
2125
},
2226
"Recommendation": {
2327
"Text": "1. From the Azure Admin Portal dashboard, open Microsoft Entra ID. 2. Click Security in the Entra ID blade. 3. Click Conditional Access in the Security blade. 4. Click Policies in the Conditional Access blade. 5. Click + New policy. 6. Enter a name for the policy. 7. Click the blue text under Users. 8. Under Include, select All users. 9. Under Exclude, check Users and groups. 10. Select users or groups to be exempted from this policy (e.g. break-glass emergency accounts, and non-interactive service accounts) then click the Select button. 11. Click the blue text under Target Resources. 12. Under Include, click the Select apps radio button. 13. Click the blue text under Select. 14. Check the box next to Windows Azure Service Management APIs then click the Select button. 15. Click the blue text under Grant. 16. Under Grant access check the box for Require multifactor authentication then click the Select button. 17. Before creating, set Enable policy to Report-only. 18. Click Create. After testing the policy in report-only mode, update the Enable policy setting from Report-only to On.",

0 commit comments

Comments
 (0)