Compare commits

...

5 Commits

Author SHA1 Message Date
HugoPBrito
2ba1a5990a feat: add docstrings 2025-02-12 16:43:22 +01:00
HugoPBrito
2b7dead1f8 feat: rename and adapt logic 2025-02-12 16:37:50 +01:00
HugoPBrito
4aa6e220b0 feat: add service test 2025-02-11 15:48:36 +01:00
HugoPBrito
3f57d0436f feat: add tests 2025-02-10 17:05:50 +01:00
HugoPBrito
1a7f5e7c9a feat: add check logic and metadata 2025-02-10 17:05:13 +01:00
6 changed files with 214 additions and 3 deletions

View File

@@ -0,0 +1,30 @@
{
"Provider": "microsoft365",
"CheckID": "entra_security_defaults_disabled",
"CheckTitle": "Ensure Security Defaults is disabled on Microsoft Entra ID",
"CheckType": [],
"ServiceName": "entra",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "#microsoft.graph.identitySecurityDefaultsEnforcementPolicy",
"Description": "Disabling Security Defaults allows organizations to implement more granular and advanced security controls beyond the predefined settings. This ensures that security policies are aligned with organizational requirements rather than relying on a one-size-fits-all approach.",
"Risk": "Security Defaults in Microsoft Entra ID provide preconfigured security settings to protect organizations from common attacks. While these defaults enhance security by enforcing MFA, blocking legacy authentication, and implementing other protections, they may also prevent organizations from applying custom security policies tailored to their specific needs.",
"RelatedUrl": "https://learn.microsoft.com/en-us/entra/fundamentals/security-defaults",
"Remediation": {
"Code": {
"CLI": "Update-MgPolicyIdentitySecurityDefaultEnforcementPolicy -BodyParameter @{ IsEnabled = $false }",
"NativeIaC": "",
"Other": "",
"Terraform": ""
},
"Recommendation": {
"Text": "1. Navigate to Microsoft Entra admin center. 2. Click to expand Identity > Overview 3. Click Propierties 4. Click Manage security defaults 5. Set the Security defaults dropdown to Disabled 6. Select Save",
"Url": "https://techcommunity.microsoft.com/t5/microsoft-entra-blog/introducing-security-defaults/ba-p/1061414"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": "Before disabling Security Defaults, ensure robust security measures are in place, including enforced MFA, blocked legacy authentication, Conditional Access policies, and continuous identity threat monitoring.. Administrators should also be aware that certain configurations in Microsoft Entra ID may impact other Microsoft services such as Azure."
}

View File

@@ -0,0 +1,42 @@
from typing import List
from prowler.lib.check.models import Check, Check_Report_Microsoft365
from prowler.providers.microsoft365.services.entra.entra_client import entra_client
class entra_security_defaults_disabled(Check):
"""Check if Entra Security Defaults are disabled.
This check verifies if the Entra Security Defaults are disabled in the Microsoft 365 environment.
The check passes if security defaults are disabled, and fails if they are enabled.
Attributes:
metadata: Metadata associated with the check (inherited from Check).
"""
def execute(self) -> List[Check_Report_Microsoft365]:
"""Execute the Entra Security Defaults disabled check.
This method checks the status of Entra Security Defaults and generates a report indicating
whether security defaults are disabled or not.
Returns:
List[Check_Report_Microsoft365]: A list containing the report of the check, indicating
whether the security defaults are disabled or enabled.
"""
findings = []
report = Check_Report_Microsoft365(
metadata=self.metadata(), resource=entra_client.security_defaults
)
report.status = "FAIL"
report.status_extended = "Entra Security Defaults is not disabled."
if (
entra_client.security_defaults is not None
and not entra_client.security_defaults.is_enabled
):
report.status = "PASS"
report.status_extended = "Entra Security Defaults is disabled."
findings.append(report)
return findings

View File

@@ -15,12 +15,11 @@ class Entra(Microsoft365Service):
loop = get_event_loop()
attributes = loop.run_until_complete(
gather(
self._get_authorization_policy(),
)
gather(self._get_authorization_policy(), self._get_security_default())
)
self.authorization_policy = attributes[0]
self.security_defaults = attributes[1]
async def _get_authorization_policy(self):
logger.info("Entra - Getting authorization policy...")
@@ -83,6 +82,29 @@ class Entra(Microsoft365Service):
return authorization_policy
async def _get_security_default(self):
logger.info("Entra - Getting security default...")
try:
security_defaults = (
await self.client.policies.identity_security_defaults_enforcement_policy.get()
)
return SecurityDefaults(
id=security_defaults.id,
name=security_defaults.display_name,
is_enabled=security_defaults.is_enabled,
)
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
return None
class SecurityDefaults(BaseModel):
id: str
name: str
is_enabled: bool
class DefaultUserRolePermissions(BaseModel):
allowed_to_create_apps: Optional[bool]

View File

@@ -0,0 +1,98 @@
from unittest import mock
from uuid import uuid4
from tests.providers.microsoft365.microsoft365_fixtures import (
set_mocked_microsoft365_provider,
)
class Test_entra_security_defaults_disabled:
def test_entra_tenant_empty(self):
entra_client = mock.MagicMock
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_security_defaults_disabled.entra_security_defaults_disabled.entra_client",
new=entra_client,
):
from prowler.providers.microsoft365.services.entra.entra_security_defaults_disabled.entra_security_defaults_disabled import (
entra_security_defaults_disabled,
)
entra_client.security_defaults = None
check = entra_security_defaults_disabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended == "Entra Security Defaults is not disabled."
)
assert result[0].resource_name == ""
assert result[0].resource_id == ""
def test_entra_security_defaults_enabled(self):
entra_client = mock.MagicMock
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_security_defaults_disabled.entra_security_defaults_disabled.entra_client",
new=entra_client,
):
from prowler.providers.microsoft365.services.entra.entra_security_defaults_disabled.entra_security_defaults_disabled import (
entra_security_defaults_disabled,
)
from prowler.providers.microsoft365.services.entra.entra_service import (
SecurityDefaults,
)
id = str(uuid4())
entra_client.security_defaults = SecurityDefaults(
id=id, name="Sec Default", is_enabled=True
)
check = entra_security_defaults_disabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended == "Entra Security Defaults is not disabled."
)
assert result[0].resource_name == "Sec Default"
assert result[0].resource_id == id
def test_entra_security_default_disabled(self):
entra_client = mock.MagicMock
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_security_defaults_disabled.entra_security_defaults_disabled.entra_client",
new=entra_client,
):
from prowler.providers.microsoft365.services.entra.entra_security_defaults_disabled.entra_security_defaults_disabled import (
entra_security_defaults_disabled,
)
from prowler.providers.microsoft365.services.entra.entra_service import (
SecurityDefaults,
)
id = str(uuid4())
entra_client.security_defaults = SecurityDefaults(
id=id, name="Sec Default", is_enabled=False
)
check = entra_security_defaults_disabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert result[0].status_extended == "Entra Security Defaults is disabled."
assert result[0].resource_name == "Sec Default"
assert result[0].resource_id == id

View File

@@ -4,6 +4,7 @@ from prowler.providers.microsoft365.models import Microsoft365IdentityInfo
from prowler.providers.microsoft365.services.entra.entra_service import (
AuthorizationPolicy,
Entra,
SecurityDefaults,
)
from tests.providers.microsoft365.microsoft365_fixtures import (
DOMAIN,
@@ -22,6 +23,14 @@ async def mock_entra_get_authorization_policy(_):
}
async def mock_entra_get_security_default(_):
return SecurityDefaults(
id="id-1",
name="Name 1",
is_enabled=True,
)
@patch(
"prowler.providers.microsoft365.services.entra.entra_service.Entra._get_authorization_policy",
new=mock_entra_get_authorization_policy,
@@ -43,3 +52,13 @@ class Test_Entra_Service:
assert not entra_client.authorization_policy[
"id-1"
].default_user_role_permissions
@patch(
"prowler.providers.microsoft365.services.entra.entra_service.Entra._get_security_default",
new=mock_entra_get_security_default,
)
def test_get_security_defaults(self):
entra_client = Entra(set_mocked_microsoft365_provider())
assert entra_client.security_defaults.id == "id-1"
assert entra_client.security_defaults.name == "Name 1"
assert entra_client.security_defaults.is_enabled