feat(defender): add new check defender_antiphishing_policy_configured (#7453)

This commit is contained in:
Daniel Barranquero authored and Adrián Jesús Peña Rodríguez committed 2025-04-22 16:11:47 +02:00
1 parent 972c88e421
commit 7800320189
8 files changed
+625 -2

No files matched your search

@@ -0,0 +1,320 @@
from unittest import mock
from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
class Test_defender_antiphishing_policy_configured:
def test_properly_configured_custom_policy(self):
defender_client = mock.MagicMock()
defender_client.audited_tenant = "audited_tenant"
defender_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured.defender_client",
new=defender_client,
),
):
from prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured import (
defender_antiphishing_policy_configured,
)
from prowler.providers.m365.services.defender.defender_service import (
AntiphishingPolicy,
AntiphishingRule,
)
defender_client.antiphishing_policies = {
"Policy1": AntiphishingPolicy(
spoof_intelligence=True,
spoof_intelligence_action="Quarantine",
dmarc_reject_action="Quarantine",
dmarc_quarantine_action="Quarantine",
safety_tips=True,
unauthenticated_sender_action=True,
show_tag=True,
honor_dmarc_policy=True,
default=False,
)
}
defender_client.antiphising_rules = {
"Policy1": AntiphishingRule(state="Enabled")
}
check = defender_antiphishing_policy_configured()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "Anti-phishing policy Policy1 is properly configured and enabled."
)
assert (
result[0].resource
== defender_client.antiphishing_policies["Policy1"].dict()
)
assert result[0].resource_name == "Defender Anti-Phishing Policy"
assert result[0].resource_id == "Policy1"
assert result[0].location == "global"
def test_not_properly_configured_policy(self):
defender_client = mock.MagicMock()
defender_client.audited_tenant = "audited_tenant"
defender_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured.defender_client",
new=defender_client,
),
):
from prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured import (
defender_antiphishing_policy_configured,
)
from prowler.providers.m365.services.defender.defender_service import (
AntiphishingPolicy,
AntiphishingRule,
)
defender_client.antiphishing_policies = {
"Policy2": AntiphishingPolicy(
spoof_intelligence=False,
spoof_intelligence_action="None",
dmarc_reject_action="None",
dmarc_quarantine_action="None",
safety_tips=False,
unauthenticated_sender_action=False,
show_tag=False,
honor_dmarc_policy=False,
default=False,
)
}
defender_client.antiphising_rules = {
"Policy2": AntiphishingRule(state="Enabled")
}
check = defender_antiphishing_policy_configured()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Anti-phishing policy Policy2 is not properly configured."
)
assert (
result[0].resource
== defender_client.antiphishing_policies["Policy2"].dict()
)
assert result[0].resource_name == "Defender Anti-Phishing Policy"
assert result[0].resource_id == "Policy2"
assert result[0].location == "global"
def test_properly_configured_default_policy(self):
defender_client = mock.MagicMock()
defender_client.audited_tenant = "audited_tenant"
defender_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured.defender_client",
new=defender_client,
),
):
from prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured import (
defender_antiphishing_policy_configured,
)
from prowler.providers.m365.services.defender.defender_service import (
AntiphishingPolicy,
)
defender_client.antiphishing_policies = {
"Default": AntiphishingPolicy(
spoof_intelligence=True,
spoof_intelligence_action="Quarantine",
dmarc_reject_action="Quarantine",
dmarc_quarantine_action="Quarantine",
safety_tips=True,
unauthenticated_sender_action=True,
show_tag=True,
honor_dmarc_policy=True,
default=True,
)
}
defender_client.antiphising_rules = {}
check = defender_antiphishing_policy_configured()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "Anti-phishing policy Default is properly configured and enabled."
)
assert (
result[0].resource
== defender_client.antiphishing_policies["Default"].dict()
)
assert result[0].resource_name == "Defender Anti-Phishing Policy"
assert result[0].resource_id == "Default"
assert result[0].location == "global"
def test_default_policy_not_properly_configured(self):
defender_client = mock.MagicMock()
defender_client.audited_tenant = "audited_tenant"
defender_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured.defender_client",
new=defender_client,
),
):
from prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured import (
defender_antiphishing_policy_configured,
)
from prowler.providers.m365.services.defender.defender_service import (
AntiphishingPolicy,
)
defender_client.antiphishing_policies = {
"Default": AntiphishingPolicy(
spoof_intelligence=False,
spoof_intelligence_action="None",
dmarc_reject_action="None",
dmarc_quarantine_action="None",
safety_tips=False,
unauthenticated_sender_action=False,
show_tag=False,
honor_dmarc_policy=False,
default=True,
)
}
defender_client.antiphising_rules = {}
check = defender_antiphishing_policy_configured()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Anti-phishing policy Default is not properly configured."
)
assert (
result[0].resource
== defender_client.antiphishing_policies["Default"].dict()
)
assert result[0].resource_name == "Defender Anti-Phishing Policy"
assert result[0].resource_id == "Default"
assert result[0].location == "global"
def test_no_antiphishing_policies(self):
defender_client = mock.MagicMock()
defender_client.audited_tenant = "audited_tenant"
defender_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured.defender_client",
new=defender_client,
),
):
from prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured import (
defender_antiphishing_policy_configured,
)
defender_client.antiphishing_policies = {}
defender_client.antiphising_rules = {}
check = defender_antiphishing_policy_configured()
result = check.execute()
assert result == []
def test_custom_policy_without_rule(self):
defender_client = mock.MagicMock()
defender_client.audited_tenant = "audited_tenant"
defender_client.audited_domain = DOMAIN
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_m365_provider(),
),
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured.defender_client",
new=defender_client,
),
):
from prowler.providers.m365.services.defender.defender_antiphishing_policy_configured.defender_antiphishing_policy_configured import (
defender_antiphishing_policy_configured,
)
from prowler.providers.m365.services.defender.defender_service import (
AntiphishingPolicy,
)
defender_client.antiphishing_policies = {
"PolicyX": AntiphishingPolicy(
spoof_intelligence=True,
spoof_intelligence_action="Quarantine",
dmarc_reject_action="Quarantine",
dmarc_quarantine_action="Quarantine",
safety_tips=True,
unauthenticated_sender_action=True,
show_tag=True,
honor_dmarc_policy=True,
default=False,
)
}
defender_client.antiphising_rules = {}
check = defender_antiphishing_policy_configured()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Anti-phishing policy PolicyX is not properly configured."
)
assert (
result[0].resource
== defender_client.antiphishing_policies["PolicyX"].dict()
)
assert result[0].resource_name == "Defender Anti-Phishing Policy"
assert result[0].resource_id == "PolicyX"
assert result[0].location == "global"
@@ -3,6 +3,8 @@ from unittest.mock import patch
from prowler.providers.m365.models import M365IdentityInfo
from prowler.providers.m365.services.defender.defender_service import (
AntiphishingPolicy,
AntiphishingRule,
Defender,
DefenderMalwarePolicy,
)
@@ -26,6 +28,44 @@ def mock_defender_get_malware_filter_policy(_):
]
def mock_defender_get_antiphising_policy(_):
return {
"Policy1": AntiphishingPolicy(
spoof_intelligence=True,
spoof_intelligence_action="Quarantine",
dmarc_reject_action="Reject",
dmarc_quarantine_action="Quarantine",
safety_tips=True,
unauthenticated_sender_action=True,
show_tag=True,
honor_dmarc_policy=True,
default=False,
),
"Policy2": AntiphishingPolicy(
spoof_intelligence=False,
spoof_intelligence_action="None",
dmarc_reject_action="None",
dmarc_quarantine_action="None",
safety_tips=False,
unauthenticated_sender_action=False,
show_tag=False,
honor_dmarc_policy=False,
default=True,
),
}
def mock_defender_get_antiphising_rules(_):
return {
"Policy1": AntiphishingRule(
state="Enabled",
),
"Policy2": AntiphishingRule(
state="Disabled",
),
}
class Test_Defender_Service:
def test_get_client(self):
with (
@@ -58,8 +98,6 @@ class Test_Defender_Service:
)
)
malware_policies = defender_client.malware_policies
assert malware_policies[0].enable_file_filter is False
assert malware_policies[0].identity == "Policy1"
assert (
malware_policies[0].enable_internal_sender_admin_notifications is False
)
@@ -73,3 +111,69 @@ class Test_Defender_Service:
malware_policies[1].internal_sender_admin_address
== "security@example.com"
)
defender_client.powershell.close()
@patch(
"prowler.providers.m365.services.defender.defender_service.Defender._get_antiphising_policy",
new=mock_defender_get_antiphising_policy,
)
def test_get_antiphising_policy(self):
with (
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
):
defender_client = Defender(
set_mocked_m365_provider(
identity=M365IdentityInfo(tenant_domain=DOMAIN)
)
)
antiphishing_policies = defender_client.antiphishing_policies
assert antiphishing_policies["Policy1"].spoof_intelligence is True
assert (
antiphishing_policies["Policy1"].spoof_intelligence_action
== "Quarantine"
)
assert antiphishing_policies["Policy1"].dmarc_reject_action == "Reject"
assert (
antiphishing_policies["Policy1"].dmarc_quarantine_action == "Quarantine"
)
assert antiphishing_policies["Policy1"].safety_tips is True
assert (
antiphishing_policies["Policy1"].unauthenticated_sender_action is True
)
assert antiphishing_policies["Policy1"].show_tag is True
assert antiphishing_policies["Policy1"].honor_dmarc_policy is True
assert antiphishing_policies["Policy1"].default is False
assert antiphishing_policies["Policy2"].spoof_intelligence is False
assert antiphishing_policies["Policy2"].spoof_intelligence_action == "None"
assert antiphishing_policies["Policy2"].dmarc_reject_action == "None"
assert antiphishing_policies["Policy2"].dmarc_quarantine_action == "None"
assert antiphishing_policies["Policy2"].safety_tips is False
assert (
antiphishing_policies["Policy2"].unauthenticated_sender_action is False
)
assert antiphishing_policies["Policy2"].show_tag is False
assert antiphishing_policies["Policy2"].honor_dmarc_policy is False
assert antiphishing_policies["Policy2"].default is True
defender_client.powershell.close()
@patch(
"prowler.providers.m365.services.defender.defender_service.Defender._get_antiphising_rules",
new=mock_defender_get_antiphising_rules,
)
def test_get_antiphising_rules(self):
with (
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
):
defender_client = Defender(
set_mocked_m365_provider(
identity=M365IdentityInfo(tenant_domain=DOMAIN)
)
)
antiphishing_rules = defender_client.antiphising_rules
assert antiphishing_rules["Policy1"].state == "Enabled"
assert antiphishing_rules["Policy2"].state == "Disabled"
defender_client.powershell.close()