feat(m365): add entra_app_enforced_restrictions security check (#10058)

This commit is contained in:
Hugo Pereira Brito
2026-02-25 11:53:35 +01:00
committed by GitHub
parent e47f2b4033
commit 6935c4eb1b
22 changed files with 1418 additions and 79 deletions

View File

@@ -6,6 +6,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
### 🚀 Added
- `entra_app_enforced_restrictions` check for M365 provider [(#10058)](https://github.com/prowler-cloud/prowler/pull/10058)
- `entra_app_registration_no_unused_privileged_permissions` check for m365 provider [(#10080)](https://github.com/prowler-cloud/prowler/pull/10080)
- `defenderidentity_health_issues_no_open` check for M365 provider [(#10087)](https://github.com/prowler-cloud/prowler/pull/10087)
- `organization_verified_badge` check for GitHub provider [(#10033)](https://github.com/prowler-cloud/prowler/pull/10033)

View File

@@ -174,16 +174,17 @@
}
],
"Checks": [
"teams_external_file_sharing_restricted",
"entra_app_enforced_restrictions",
"exchange_transport_config_smtp_auth_disabled",
"exchange_transport_rules_mail_forwarding_disabled",
"exchange_transport_rules_whitelist_disabled",
"sharepoint_external_sharing_managed",
"sharepoint_external_sharing_restricted",
"sharepoint_guest_sharing_restricted",
"sharepoint_modern_authentication_required",
"sharepoint_onedrive_sync_restricted_unmanaged_devices",
"teams_external_file_sharing_restricted",
"exchange_transport_config_smtp_auth_disabled",
"exchange_transport_rules_mail_forwarding_disabled",
"exchange_transport_rules_whitelist_disabled"
"teams_external_file_sharing_restricted"
]
},
{
@@ -612,11 +613,12 @@
],
"Checks": [
"defenderxdr_endpoint_privileged_user_exposed_credentials",
"entra_managed_device_required_for_authentication",
"entra_users_mfa_enabled",
"entra_managed_device_required_for_mfa_registration",
"entra_admin_users_phishing_resistant_mfa_enabled",
"entra_users_mfa_capable"
"entra_app_enforced_restrictions",
"entra_managed_device_required_for_authentication",
"entra_managed_device_required_for_mfa_registration",
"entra_users_mfa_capable",
"entra_users_mfa_enabled"
]
},
{
@@ -665,9 +667,10 @@
}
],
"Checks": [
"sharepoint_external_sharing_restricted",
"entra_admin_portals_access_restriction",
"entra_policy_guest_users_access_restrictions"
"entra_app_enforced_restrictions",
"entra_policy_guest_users_access_restrictions",
"sharepoint_external_sharing_restricted"
]
},
{
@@ -749,7 +752,8 @@
"Checks": [
"defender_antiphishing_policy_configured",
"defender_safelinks_policy_enabled",
"entra_admin_users_phishing_resistant_mfa_enabled"
"entra_admin_users_phishing_resistant_mfa_enabled",
"entra_app_enforced_restrictions"
]
},
{

View File

@@ -823,6 +823,7 @@
"Id": "1.3.9",
"Description": "Ensure OneDrive sync is restricted for unmanaged devices",
"Checks": [
"entra_app_enforced_restrictions",
"sharepoint_onedrive_sync_restricted_unmanaged_devices"
],
"Attributes": [

View File

@@ -0,0 +1,39 @@
{
"Provider": "m365",
"CheckID": "entra_app_enforced_restrictions",
"CheckTitle": "Conditional Access policy enforces application restrictions for unmanaged devices",
"CheckType": [],
"ServiceName": "entra",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "medium",
"ResourceType": "Conditional Access Policy",
"ResourceGroup": "IAM",
"Description": "Conditional Access policy with **application enforced restrictions** limits access to SharePoint, OneDrive, and Exchange content from unmanaged devices.\n\nThis control helps prevent data exfiltration by restricting download, print, and sync capabilities on devices that are not managed by the organization.",
"Risk": "Without application enforced restrictions, users accessing SharePoint, OneDrive, and Exchange from unmanaged devices can:\n\n- **Download** sensitive files to personal devices\n- **Print** confidential documents\n- **Sync** corporate data to uncontrolled locations\n\nThis increases the risk of data leakage and unauthorized access to sensitive information.",
"RelatedUrl": "",
"AdditionalURLs": [
"https://learn.microsoft.com/en-us/entra/identity/conditional-access/howto-policy-app-enforced-restriction",
"https://learn.microsoft.com/en-us/sharepoint/control-access-from-unmanaged-devices"
],
"Remediation": {
"Code": {
"CLI": "",
"NativeIaC": "",
"Other": "1. Navigate to the Microsoft Entra admin center https://entra.microsoft.com.\n2. Expand **Protection** > **Conditional Access** and select **Policies**.\n3. Click **New policy**.\n4. Under **Users**, select **All users**.\n5. Under **Target resources**, select **Office 365** from the cloud apps.\n6. Under **Conditions** > **Client apps**, select **All client apps**.\n7. Under **Session**, check **Use app enforced restrictions**.\n8. Set the policy to **On** and click **Create**.",
"Terraform": ""
},
"Recommendation": {
"Text": "Configure Conditional Access policies with **application enforced restrictions** to control access from unmanaged devices. Apply this to Office 365 applications (SharePoint, OneDrive, Exchange) to limit download, print, and sync operations.\n\nCombine with SharePoint access control settings for comprehensive protection.",
"Url": "https://hub.prowler.com/check/entra_app_enforced_restrictions"
}
},
"Categories": [
"e3"
],
"DependsOn": [],
"RelatedTo": [
"entra_managed_device_required_for_authentication"
],
"Notes": "Application enforced restrictions only work with Exchange Online and SharePoint Online (including OneDrive)."
}

View File

@@ -0,0 +1,108 @@
from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.entra.entra_client import entra_client
from prowler.providers.m365.services.entra.entra_service import (
ClientAppType,
ConditionalAccessPolicyState,
)
class entra_app_enforced_restrictions(Check):
"""Check if at least one Conditional Access policy enforces application restrictions.
This check verifies that the tenant has at least one enabled Conditional Access policy
with application enforced restrictions to protect SharePoint, OneDrive, and Exchange
from unmanaged devices.
- PASS: At least one policy is enabled with application enforced restrictions targeting
all users, all client app types, and either the Office365 suite or
SharePoint Online and Exchange Online individually.
- FAIL: No policy meets the criteria for application enforced restrictions.
"""
# SharePoint Online / OneDrive for Business
SHAREPOINT_APP_ID = "00000003-0000-0ff1-ce00-000000000000"
# Exchange Online
EXCHANGE_APP_ID = "00000002-0000-0ff1-ce00-000000000000"
# Office 365 suite (includes SharePoint, OneDrive, and Exchange)
OFFICE365_APP_ID = "Office365"
REQUIRED_APPS = {SHAREPOINT_APP_ID, EXCHANGE_APP_ID}
MODERN_CLIENT_APP_TYPES = {
ClientAppType.BROWSER,
ClientAppType.MOBILE_APPS_AND_DESKTOP_CLIENTS,
}
def _targets_all_client_apps(self, client_app_types: list[ClientAppType]) -> bool:
"""Check if the policy targets all modern client app types.
Returns True if the policy includes ALL explicitly or both
Browser and Mobile apps and desktop clients.
"""
client_app_set = set(client_app_types)
if ClientAppType.ALL in client_app_set:
return True
return self.MODERN_CLIENT_APP_TYPES.issubset(client_app_set)
def _targets_required_apps(self, included_applications: list[str]) -> bool:
"""Check if the policy targets the required applications.
Returns True if the policy includes Office365 (the suite) or both
SharePoint Online and Exchange Online individually.
"""
if self.OFFICE365_APP_ID in included_applications:
return True
return self.REQUIRED_APPS.issubset(set(included_applications))
def execute(self) -> list[CheckReportM365]:
"""Execute the check for application enforced restrictions in Conditional Access policies.
Returns:
list[CheckReportM365]: A list containing the result of the check.
"""
findings = []
report = CheckReportM365(
metadata=self.metadata(),
resource={},
resource_name="Conditional Access Policies",
resource_id="conditionalAccessPolicies",
)
report.status = "FAIL"
report.status_extended = "No Conditional Access Policy enforces application restrictions for unmanaged devices."
for policy in entra_client.conditional_access_policies.values():
if policy.state == ConditionalAccessPolicyState.DISABLED:
continue
if "All" not in policy.conditions.user_conditions.included_users:
continue
if not self._targets_all_client_apps(policy.conditions.client_app_types):
continue
if not self._targets_required_apps(
policy.conditions.application_conditions.included_applications
):
continue
if (
not policy.session_controls.application_enforced_restrictions
or not policy.session_controls.application_enforced_restrictions.is_enabled
):
continue
report = CheckReportM365(
metadata=self.metadata(),
resource=policy,
resource_name=policy.display_name,
resource_id=policy.id,
)
if policy.state == ConditionalAccessPolicyState.ENABLED_FOR_REPORTING:
report.status = "FAIL"
report.status_extended = f"Conditional Access Policy {policy.display_name} reports application enforced restrictions but does not enforce them."
else:
report.status = "PASS"
report.status_extended = f"Conditional Access Policy {policy.display_name} enforces application restrictions for unmanaged devices."
break
findings.append(report)
return findings

View File

@@ -84,28 +84,25 @@ class entra_emergency_access_exclusion(Check):
users_excluded_from_all or groups_excluded_from_all
)
for policy in enabled_policies:
report = CheckReportM365(
metadata=self.metadata(),
resource=policy,
resource_name=policy.display_name,
resource_id=policy.id,
)
report = CheckReportM365(
metadata=self.metadata(),
resource={},
resource_name="Conditional Access Policies",
resource_id="conditionalAccessPolicies",
)
if has_emergency_exclusion:
report.status = "PASS"
exclusion_details = []
if users_excluded_from_all:
exclusion_details.append(f"{len(users_excluded_from_all)} user(s)")
if groups_excluded_from_all:
exclusion_details.append(
f"{len(groups_excluded_from_all)} group(s)"
)
report.status_extended = f"Conditional Access Policy '{policy.display_name}' has {' and '.join(exclusion_details)} excluded as emergency access across all {total_policy_count} enabled policies."
else:
report.status = "FAIL"
report.status_extended = f"Conditional Access Policy '{policy.display_name}' does not have any user or group excluded as emergency access from all enabled Conditional Access policies."
if has_emergency_exclusion:
report.status = "PASS"
exclusion_details = []
if users_excluded_from_all:
exclusion_details.append(f"{len(users_excluded_from_all)} user(s)")
if groups_excluded_from_all:
exclusion_details.append(f"{len(groups_excluded_from_all)} group(s)")
report.status_extended = f"{' and '.join(exclusion_details)} excluded as emergency access across all {total_policy_count} enabled Conditional Access policies."
else:
report.status = "FAIL"
report.status_extended = f"No user or group is excluded as emergency access from all {total_policy_count} enabled Conditional Access policies."
findings.append(report)
findings.append(report)
return findings

View File

@@ -341,6 +341,14 @@ class Entra(M365Service):
else None
),
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=(
policy.session_controls.application_enforced_restrictions.is_enabled
if policy.session_controls
and policy.session_controls.application_enforced_restrictions
else False
),
),
),
state=ConditionalAccessPolicyState(
getattr(policy, "state", "disabled")
@@ -735,9 +743,18 @@ class SignInFrequency(BaseModel):
interval: Optional[SignInFrequencyInterval]
class ApplicationEnforcedRestrictions(BaseModel):
"""Model representing application enforced restrictions session control."""
is_enabled: bool = False
class SessionControls(BaseModel):
"""Model representing session controls for Conditional Access policies."""
persistent_browser: PersistentBrowser
sign_in_frequency: SignInFrequency
application_enforced_restrictions: Optional[ApplicationEnforcedRestrictions] = None
class ConditionalAccessGrantControl(Enum):

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
@@ -106,6 +107,9 @@ class Test_entra_admin_portals_access_restriction:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -181,6 +185,9 @@ class Test_entra_admin_portals_access_restriction:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -259,6 +266,9 @@ class Test_entra_admin_portals_access_restriction:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicy,
@@ -108,6 +109,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -184,6 +188,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -260,6 +267,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -341,6 +351,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -436,6 +449,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -530,6 +546,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -626,6 +645,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
),
@@ -677,6 +699,9 @@ class Test_entra_admin_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
),

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
@@ -125,6 +126,9 @@ class Test_entra_admin_users_phishing_resistant_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -217,6 +221,9 @@ class Test_entra_admin_users_phishing_resistant_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -312,6 +319,9 @@ class Test_entra_admin_users_phishing_resistant_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessPolicyState,
Conditions,
@@ -108,6 +109,9 @@ class Test_entra_admin_users_sign_in_frequency_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -200,6 +204,9 @@ class Test_entra_admin_users_sign_in_frequency_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -298,6 +305,9 @@ class Test_entra_admin_users_sign_in_frequency_enabled:
type=SignInFrequencyType.HOURS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -393,6 +403,9 @@ class Test_entra_admin_users_sign_in_frequency_enabled:
type=SignInFrequencyType.HOURS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -488,6 +501,9 @@ class Test_entra_admin_users_sign_in_frequency_enabled:
type=SignInFrequencyType.HOURS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -586,6 +602,9 @@ class Test_entra_admin_users_sign_in_frequency_enabled:
type=SignInFrequencyType.DAYS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -225,17 +225,14 @@ class Test_entra_emergency_access_exclusion:
check = entra_emergency_access_exclusion()
result = check.execute()
assert len(result) == 2
for finding in result:
assert finding.status == "FAIL"
assert (
"does not have any user or group excluded as emergency access"
in finding.status_extended
)
assert result[0].resource_name == "Policy 1"
assert result[0].resource_id == policy_id_1
assert result[1].resource_name == "Policy 2"
assert result[1].resource_id == policy_id_2
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
"No user or group is excluded as emergency access from all 2 enabled Conditional Access policies"
in result[0].status_extended
)
assert result[0].resource_name == "Conditional Access Policies"
assert result[0].resource_id == "conditionalAccessPolicies"
def test_entra_user_excluded_from_all_policies(self):
"""Test when a user is excluded from all enabled policies."""
@@ -339,17 +336,14 @@ class Test_entra_emergency_access_exclusion:
check = entra_emergency_access_exclusion()
result = check.execute()
assert len(result) == 2
for finding in result:
assert finding.status == "PASS"
assert (
"1 user(s) excluded as emergency access across all 2 enabled policies"
in finding.status_extended
)
assert result[0].resource_name == "Policy 1"
assert result[0].resource_id == policy_id_1
assert result[1].resource_name == "Policy 2"
assert result[1].resource_id == policy_id_2
assert len(result) == 1
assert result[0].status == "PASS"
assert (
"1 user(s) excluded as emergency access across all 2 enabled Conditional Access policies"
in result[0].status_extended
)
assert result[0].resource_name == "Conditional Access Policies"
assert result[0].resource_id == "conditionalAccessPolicies"
def test_entra_group_excluded_from_all_policies(self):
"""Test when a group is excluded from all enabled policies."""
@@ -453,13 +447,14 @@ class Test_entra_emergency_access_exclusion:
check = entra_emergency_access_exclusion()
result = check.execute()
assert len(result) == 2
for finding in result:
assert finding.status == "PASS"
assert (
"1 group(s) excluded as emergency access across all 2 enabled policies"
in finding.status_extended
)
assert len(result) == 1
assert result[0].status == "PASS"
assert (
"1 group(s) excluded as emergency access across all 2 enabled Conditional Access policies"
in result[0].status_extended
)
assert result[0].resource_name == "Conditional Access Policies"
assert result[0].resource_id == "conditionalAccessPolicies"
def test_entra_user_and_group_excluded_from_all_policies(self):
"""Test when both a user and group are excluded from all enabled policies."""
@@ -564,13 +559,14 @@ class Test_entra_emergency_access_exclusion:
check = entra_emergency_access_exclusion()
result = check.execute()
assert len(result) == 2
for finding in result:
assert finding.status == "PASS"
assert (
"1 user(s) and 1 group(s) excluded as emergency access across all 2 enabled policies"
in finding.status_extended
)
assert len(result) == 1
assert result[0].status == "PASS"
assert (
"1 user(s) and 1 group(s) excluded as emergency access across all 2 enabled Conditional Access policies"
in result[0].status_extended
)
assert result[0].resource_name == "Conditional Access Policies"
assert result[0].resource_id == "conditionalAccessPolicies"
def test_entra_disabled_policies_ignored(self):
"""Test that disabled policies are ignored when checking exclusions."""
@@ -674,13 +670,12 @@ class Test_entra_emergency_access_exclusion:
check = entra_emergency_access_exclusion()
result = check.execute()
# Only 1 enabled policy, so only 1 finding
assert len(result) == 1
assert result[0].status == "PASS"
assert result[0].resource_name == "Enabled Policy"
assert result[0].resource_id == policy_id_1
assert result[0].resource_name == "Conditional Access Policies"
assert result[0].resource_id == "conditionalAccessPolicies"
assert (
"1 user(s) excluded as emergency access across all 1 enabled policies"
"1 user(s) excluded as emergency access across all 1 enabled Conditional Access policies"
in result[0].status_extended
)
@@ -787,10 +782,11 @@ class Test_entra_emergency_access_exclusion:
check = entra_emergency_access_exclusion()
result = check.execute()
assert len(result) == 2
for finding in result:
assert finding.status == "PASS"
assert (
"1 user(s) excluded as emergency access across all 2 enabled policies"
in finding.status_extended
)
assert len(result) == 1
assert result[0].status == "PASS"
assert (
"1 user(s) excluded as emergency access across all 2 enabled Conditional Access policies"
in result[0].status_extended
)
assert result[0].resource_name == "Conditional Access Policies"
assert result[0].resource_id == "conditionalAccessPolicies"

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
@@ -109,6 +110,9 @@ class Test_entra_identity_protection_sign_in_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -189,6 +193,9 @@ class Test_entra_identity_protection_sign_in_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -272,6 +279,9 @@ class Test_entra_identity_protection_sign_in_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -355,6 +365,9 @@ class Test_entra_identity_protection_sign_in_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
@@ -108,6 +109,9 @@ class Test_entra_identity_protection_user_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -187,6 +191,9 @@ class Test_entra_identity_protection_user_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -269,6 +276,9 @@ class Test_entra_identity_protection_user_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -351,6 +361,9 @@ class Test_entra_identity_protection_user_risk_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessPolicyState,
Conditions,
@@ -108,6 +109,9 @@ class Test_entra_intune_enrollment_sign_in_frequency_every_time:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -184,6 +188,9 @@ class Test_entra_intune_enrollment_sign_in_frequency_every_time:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -258,6 +265,9 @@ class Test_entra_intune_enrollment_sign_in_frequency_every_time:
type=SignInFrequencyType.HOURS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)
@@ -334,6 +344,9 @@ class Test_entra_intune_enrollment_sign_in_frequency_every_time:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ClientAppType,
ConditionalAccessGrantControl,
@@ -116,6 +117,9 @@ class Test_entra_legacy_authentication_blocked:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -198,6 +202,9 @@ class Test_entra_legacy_authentication_blocked:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -283,6 +290,9 @@ class Test_entra_legacy_authentication_blocked:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
@@ -106,6 +107,7 @@ class Test_entra_managed_device_required_for_authentication:
type=None,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(is_enabled=False),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -184,6 +186,7 @@ class Test_entra_managed_device_required_for_authentication:
type=None,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(is_enabled=False),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -266,6 +269,7 @@ class Test_entra_managed_device_required_for_authentication:
type=None,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(is_enabled=False),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicyState,
@@ -107,6 +108,9 @@ class Test_entra_managed_device_required_for_mfa_registration:
type=None,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -185,6 +189,9 @@ class Test_entra_managed_device_required_for_mfa_registration:
type=None,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -267,6 +274,9 @@ class Test_entra_managed_device_required_for_mfa_registration:
type=None,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -2,6 +2,7 @@ from unittest import mock
from uuid import uuid4
from prowler.providers.m365.services.entra.entra_service import (
ApplicationEnforcedRestrictions,
ApplicationsConditions,
ConditionalAccessGrantControl,
ConditionalAccessPolicy,
@@ -108,6 +109,9 @@ class Test_entra_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.DISABLED,
)
@@ -189,6 +193,9 @@ class Test_entra_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -268,6 +275,9 @@ class Test_entra_users_mfa_enabled:
type=None,
interval=SignInFrequencyInterval.EVERY_TIME,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED,
)

View File

@@ -6,6 +6,7 @@ from prowler.providers.m365.models import M365IdentityInfo
from prowler.providers.m365.services.entra.entra_service import (
AdminConsentPolicy,
AdminRoles,
ApplicationEnforcedRestrictions,
ApplicationsConditions,
AuthorizationPolicy,
AuthPolicyRoles,
@@ -87,6 +88,9 @@ async def mock_entra_get_conditional_access_policies(_):
type=SignInFrequencyType.HOURS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)
@@ -238,6 +242,9 @@ class Test_Entra_Service:
type=SignInFrequencyType.HOURS,
interval=SignInFrequencyInterval.TIME_BASED,
),
application_enforced_restrictions=ApplicationEnforcedRestrictions(
is_enabled=False
),
),
state=ConditionalAccessPolicyState.ENABLED_FOR_REPORTING,
)