fix(sdk): preserve entra platform condition compatibility

- Keep platform condition aliases compatible with existing checks
- Normalize platform values before evaluating unknown-device blocks
- Update tests to cover mixed casing and alias-based input
This commit is contained in:
Hugo P.Brito committed 2026-04-07 15:28:49 +01:00
1 parent 11ff512607
commit 6451740b27
3 files changed
+43 -15

No files matched your search

@@ -20,6 +20,13 @@ class entra_conditional_access_policy_unknown_device_blocked(Check):
- FAIL: No CA policy restricts access from unrecognized device platforms.
"""
@staticmethod
def _normalize_platform(platform: object) -> str:
normalized_platform = getattr(platform, "value", platform)
return (
normalized_platform.lower() if isinstance(normalized_platform, str) else ""
)
def execute(self) -> list[CheckReportM365]:
"""Execute the check logic.
@@ -43,15 +50,29 @@ class entra_conditional_access_policy_unknown_device_blocked(Check):
if not policy.conditions.platform_conditions:
continue
if (
"all"
not in policy.conditions.platform_conditions.included_platforms
):
included_platforms = {
normalized_platform
for normalized_platform in map(
self._normalize_platform,
policy.conditions.platform_conditions.include_platforms,
)
if normalized_platform
}
excluded_platforms = {
normalized_platform
for normalized_platform in map(
self._normalize_platform,
policy.conditions.platform_conditions.exclude_platforms,
)
if normalized_platform
}
if "all" not in included_platforms:
continue
if not KNOWN_PLATFORMS.issubset(
set(policy.conditions.platform_conditions.excluded_platforms)
):
if not {
self._normalize_platform(platform) for platform in KNOWN_PLATFORMS
}.issubset(excluded_platforms):
continue
if (
@@ -9,7 +9,7 @@ from msgraph.generated.models.o_data_errors.o_data_error import ODataError
from msgraph.generated.security.microsoft_graph_security_run_hunting_query.run_hunting_query_post_request_body import (
RunHuntingQueryPostRequestBody,
)
from pydantic.v1 import BaseModel
from pydantic.v1 import BaseModel, Field
from prowler.lib.logger import logger
from prowler.providers.m365.lib.service.service import M365Service
@@ -823,8 +823,15 @@ class ClientAppType(Enum):
class PlatformConditions(BaseModel):
"""Model representing device platform conditions for Conditional Access policies."""
included_platforms: List[str] = []
excluded_platforms: List[str] = []
include_platforms: List[str] = Field(
default_factory=list, alias="included_platforms"
)
exclude_platforms: List[str] = Field(
default_factory=list, alias="excluded_platforms"
)
class Config:
allow_population_by_field_name = True
class Conditions(BaseModel):
@@ -19,7 +19,7 @@ from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
CHECK_MODULE_PATH = "prowler.providers.m365.services.entra.entra_conditional_access_policy_unknown_device_blocked.entra_conditional_access_policy_unknown_device_blocked"
KNOWN_PLATFORMS = ["android", "iOS", "windows", "macOS", "linux"]
KNOWN_PLATFORMS = ["android", "ios", "windows", "macos", "linux"]
def _default_session_controls():
@@ -51,7 +51,7 @@ def _default_conditions(**overrides):
),
client_app_types=[],
platform_conditions=PlatformConditions(
included_platforms=["all"],
included_platforms=["All"],
excluded_platforms=KNOWN_PLATFORMS,
),
user_risk_levels=[],
@@ -286,7 +286,7 @@ class Test_entra_conditional_access_policy_unknown_device_blocked:
display_name=display_name,
conditions=_default_conditions(
platform_conditions=PlatformConditions(
included_platforms=["android", "iOS"],
included_platforms=["android", "ios"],
excluded_platforms=[],
)
),
@@ -337,8 +337,8 @@ class Test_entra_conditional_access_policy_unknown_device_blocked:
display_name=display_name,
conditions=_default_conditions(
platform_conditions=PlatformConditions(
included_platforms=["all"],
excluded_platforms=["android", "iOS", "windows"],
included_platforms=["All"],
excluded_platforms=["android", "ios", "windows"],
)
),
grant_controls=_default_grant_controls(),