Back to Checks
m365

Conditional Access policy blocks access from unknown or unsupported device platforms

entra_conditional_access_policy_block_unknown_device_platforms
Service: entraSeverity: medium
OfficialBuilt-inVerified
Categories:trust-boundariese3
Resource Type:NotDefined

Microsoft Entra Conditional Access can block sign-ins from device platforms that the organization does not recognize or support. A policy that includes all platforms and excludes the known ones (Android, iOS, Windows, macOS, Linux) effectively blocks any unknown or unsupported platform, reducing the attack surface from unmanaged or unexpected devices.

Risk

Without blocking unknown device platforms, attackers may authenticate from spoofed or uncommon operating systems that bypass platform-specific security controls. This increases the risk of unauthorized access and makes it harder to enforce device compliance, potentially leading to credential theft or data exfiltration from unmanaged environments.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks entra_conditional_access_policy_block_unknown_device_platforms

Recommendation

Create a Conditional Access policy that includes all device platforms and excludes the known ones (Android, iOS, Windows, macOS, Linux), then set the grant control to Block access. This ensures that only recognized platforms can authenticate, following a zero-trust approach to device management.

Remediation

Other

1Navigate to the Microsoft Entra admin center https://entra.microsoft.com.
2Expand **Protection** > **Conditional Access** and select **Policies**.
3Select **New policy**.
4Under **Users**, include the desired scope. Microsoft recommends **All users** with appropriate exclusions.
5Under **Target resources**, include the applications or resources you want to protect. Microsoft recommends **All resources / All cloud apps**.
6Under **Conditions** > **Device platforms**, set **Configure** to **Yes**.
7Under **Include**, select **Any device**.
8Under **Exclude**, select **Android**, **iOS**, **Windows**, **macOS**, and **Linux**.
9Under **Grant**, select **Block access**.
10Set **Enable policy** to **On** and click **Create**.

Check Code

"""Check for Conditional Access policy blocking unknown or unsupported device platforms."""

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 (
    ConditionalAccessGrantControl,
    ConditionalAccessPolicyState,
)


class entra_conditional_access_policy_block_unknown_device_platforms(Check):
    """Ensure a Conditional Access policy blocks access from unknown or unsupported device platforms.

    This check verifies that at least one enabled Conditional Access policy
    blocks access when the device platform is unknown or unsupported. The
    recommended configuration includes all device platforms and excludes the
    known platforms (Android, iOS, Windows, macOS, Linux), so only
    unrecognised platforms are blocked.

    - PASS: An enabled policy blocks access from unknown or unsupported device platforms.
    - FAIL: No policy blocks access from unknown or unsupported device platforms.
    """

    KNOWN_PLATFORMS = {"android", "ios", "windows", "macos", "linux"}

    def execute(self) -> list[CheckReportM365]:
        """Execute the check logic.

        Returns:
            A list of reports 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 blocks access from unknown or unsupported device platforms."

        for policy in entra_client.conditional_access_policies.values():
            if policy.state == ConditionalAccessPolicyState.DISABLED:
                continue

            if not policy.conditions.platform_conditions:
                continue

            if "all" not in policy.conditions.platform_conditions.include_platforms:
                continue

            if not self.KNOWN_PLATFORMS.issubset(
                set(policy.conditions.platform_conditions.exclude_platforms)
            ):
                continue

            if (
                ConditionalAccessGrantControl.BLOCK
                not in policy.grant_controls.built_in_controls
            ):
                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 "
                    "blocking unknown or unsupported device platforms but does not enforce it."
                )
            else:
                report.status = "PASS"
                report.status_extended = (
                    f"Conditional Access Policy {policy.display_name} blocks "
                    "access from unknown or unsupported device platforms."
                )
                break

        findings.append(report)
        return findings