mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
feat(defender): add new check defender_malware_policy_comprehensive_attachments_filter_applied (#7661)
This commit is contained in:
committed by
GitHub
parent
6b0d73d7f9
commit
e2fd3fe36e
@@ -45,6 +45,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
|
||||
- Add new check for Auditing Mailbox on E3 users is enabled for Exchange in M365 [(#7642)](https://github.com/prowler-cloud/prowler/pull/7642)
|
||||
- Add new check for SMTP Auth disabled for Exchange in M365 [(#7640)](https://github.com/prowler-cloud/prowler/pull/7640)
|
||||
- Add new check for MailTips full enabled for Exchange in M365 [(#7637)](https://github.com/prowler-cloud/prowler/pull/7637)
|
||||
- Add new check for Comprehensive Attachments Filter Applied for Defender in M365 [(#7661)](https://github.com/prowler-cloud/prowler/pull/7661)
|
||||
- Modified check `exchange_mailbox_properties_auditing_enabled` to make it configurable [(#7662)](https://github.com/prowler-cloud/prowler/pull/7662)
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -500,6 +500,18 @@ m365:
|
||||
# Exchange
|
||||
# m365.exchange_organization_mailtips_enabled
|
||||
recommended_mailtips_large_audience_threshold: 25 # maximum number of recipients
|
||||
# Defender Malware Policy Settings
|
||||
# m365.defender_malware_policy_comprehensive_attachments_filter_applied
|
||||
# The recommended list of file extensions to be blocked, this can be changed depending on the organization needs
|
||||
default_recommended_extensions:
|
||||
[
|
||||
"ace", "ani", "apk", "app", "appx", "arj", "bat", "cab", "cmd", "com",
|
||||
"deb", "dex", "dll", "docm", "elf", "exe", "hta", "img", "iso", "jar",
|
||||
"jnlp", "kext", "lha", "lib", "library", "lnk", "lzh", "macho", "msc",
|
||||
"msi", "msix", "msp", "mst", "pif", "ppa", "ppam", "reg", "rev", "scf",
|
||||
"scr", "sct", "sys", "uif", "vb", "vbe", "vbs", "vxd", "wsc", "wsf",
|
||||
"wsh", "xll", "xz", "z"
|
||||
]
|
||||
# m365.exchange_mailbox_properties_auditing_enabled
|
||||
# Maximum number of days to keep audit logs
|
||||
audit_log_age: 90
|
||||
|
||||
@@ -249,6 +249,24 @@ class M365PowerShell(PowerShellSession):
|
||||
"""
|
||||
return self.execute("Get-MalwareFilterPolicy | ConvertTo-Json", json_parse=True)
|
||||
|
||||
def get_malware_filter_rule(self) -> dict:
|
||||
"""
|
||||
Get Defender Malware Filter Rule.
|
||||
|
||||
Retrieves the current Defender anti-malware filter rule settings.
|
||||
|
||||
Returns:
|
||||
dict: Malware filter rule settings in JSON format.
|
||||
|
||||
Example:
|
||||
>>> get_malware_filter_rule()
|
||||
{
|
||||
"Name": "Default",
|
||||
"State": "Enabled"
|
||||
}
|
||||
"""
|
||||
return self.execute("Get-MalwareFilterRule | ConvertTo-Json", json_parse=True)
|
||||
|
||||
def get_outbound_spam_filter_policy(self) -> dict:
|
||||
"""
|
||||
Get Defender Outbound Spam Filter Policy.
|
||||
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"Provider": "m365",
|
||||
"CheckID": "defender_malware_policy_comprehensive_attachments_filter_applied",
|
||||
"CheckTitle": "Ensure the Common Attachment Types Filter is enabled and applied in a comprehensive way",
|
||||
"CheckType": [],
|
||||
"ServiceName": "defender",
|
||||
"SubServiceName": "",
|
||||
"ResourceIdTemplate": "",
|
||||
"Severity": "medium",
|
||||
"ResourceType": "Defender Malware Policy",
|
||||
"Description": "Ensure that the Common Attachment Types Filter is enabled in all enabled anti-malware policies in a Comprehensive way to block known and custom malicious file types from being attached to emails. This means that the file types that the filter blocks are checked by the organization, by default all the default file types from M365 defender should be blocked but you can change that with the config file.",
|
||||
"Risk": "If this setting or the policy is not enabled, users may receive emails with malicious attachments that could contain malware, increasing the risk of endpoint infection or data compromise.",
|
||||
"RelatedUrl": "https://learn.microsoft.com/en-us/defender-office-365/anti-malware-protection-about?view=o365-worldwide#common-attachments-filter-in-anti-malware-policies",
|
||||
"Remediation": {
|
||||
"Code": {
|
||||
"CLI": "$Policy = @{Name = 'CIS L2 Attachment Policy'; EnableFileFilter = $true; }; $L2Extensions = @('ace','ani','apk','app','appx','arj','bat','cab','cmd','com','deb','dex','dll','docm','elf','exe','hta','img','iso','jar','jnlp','kext','lha','lib','library','lnk','lzh','macho','msc','msi','msix','msp','mst','pif','ppa','ppam','reg','rev','scf','scr','sct','sys','uif','vb','vbe','vbs','vxd','wsc','wsf','wsh','xll','xz','z'); New-MalwareFilterPolicy @Policy -FileTypes $L2Extensions; $Rule = @{Name = $Policy.Name; Enabled = $false; MalwareFilterPolicy = $Policy.Name; Priority = 0}; New-MalwareFilterRule @Rule",
|
||||
"NativeIaC": "",
|
||||
"Other": "1. Navigate to Microsoft 365 Defender https://security.microsoft.com. 2. Click to expand Email & collaboration and select Policies & rules. 3. On the Policies & rules page select Threat policies. 4. Under Policies, select Anti-malware and click on the Default (Default) policy. 5. On the policy page, scroll to the bottom and click Edit protection settings. 6. Check the option Enable the common attachments filter. 7. Click on select file types and select the file types you want to block. 8. Click Save. 9. Ensure the status of the policy is On",
|
||||
"Terraform": ""
|
||||
},
|
||||
"Recommendation": {
|
||||
"Text": "Enable the common attachment types filter in your default or custom anti-malware policy to prevent the delivery of emails with potentially dangerous attachments.",
|
||||
"Url": "https://learn.microsoft.com/en-us/powershell/module/exchange/set-malwarefilterpolicy?view=exchange-ps"
|
||||
}
|
||||
},
|
||||
"Categories": [],
|
||||
"DependsOn": [],
|
||||
"RelatedTo": [],
|
||||
"Notes": ""
|
||||
}
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
from typing import List
|
||||
|
||||
from prowler.lib.check.models import Check, CheckReportM365
|
||||
from prowler.providers.m365.services.defender.defender_client import defender_client
|
||||
|
||||
|
||||
class defender_malware_policy_comprehensive_attachments_filter_applied(Check):
|
||||
"""
|
||||
Verifies if the Common Attachment Types Filter is enabled in the Defender anti-malware policy in a comprehensive way.
|
||||
|
||||
Attributes:
|
||||
metadata: Metadata associated with the check (inherited from Check).
|
||||
"""
|
||||
|
||||
def execute(self) -> List[CheckReportM365]:
|
||||
"""
|
||||
Executes the check to determine if the Common Attachment Types Filter is enabled.
|
||||
|
||||
This method evaluates the Defender anti-malware policy to ensure it is enabled and the
|
||||
Common Attachment Types Filter is active and applied to the recommended file types.
|
||||
|
||||
Returns:
|
||||
List[CheckReportM365]: A list of reports with the results of the check.
|
||||
"""
|
||||
findings = []
|
||||
|
||||
# Default to Microsoft-recommended common file types
|
||||
default_recommended_extensions = [
|
||||
"ace",
|
||||
"ani",
|
||||
"apk",
|
||||
"app",
|
||||
"appx",
|
||||
"arj",
|
||||
"bat",
|
||||
"cab",
|
||||
"cmd",
|
||||
"com",
|
||||
"deb",
|
||||
"dex",
|
||||
"dll",
|
||||
"docm",
|
||||
"elf",
|
||||
"exe",
|
||||
"hta",
|
||||
"img",
|
||||
"iso",
|
||||
"jar",
|
||||
"jnlp",
|
||||
"kext",
|
||||
"lha",
|
||||
"lib",
|
||||
"library",
|
||||
"lnk",
|
||||
"lzh",
|
||||
"macho",
|
||||
"msc",
|
||||
"msi",
|
||||
"msix",
|
||||
"msp",
|
||||
"mst",
|
||||
"pif",
|
||||
"ppa",
|
||||
"ppam",
|
||||
"reg",
|
||||
"rev",
|
||||
"scf",
|
||||
"scr",
|
||||
"sct",
|
||||
"sys",
|
||||
"uif",
|
||||
"vb",
|
||||
"vbe",
|
||||
"vbs",
|
||||
"vxd",
|
||||
"wsc",
|
||||
"wsf",
|
||||
"wsh",
|
||||
"xll",
|
||||
"xz",
|
||||
"z",
|
||||
]
|
||||
|
||||
# Load extensions from audit_config (user config), fallback to default
|
||||
recommended_extensions = defender_client.audit_config.get(
|
||||
"recommended_blocked_file_types", default_recommended_extensions
|
||||
)
|
||||
|
||||
if not defender_client.malware_policies:
|
||||
report = CheckReportM365(
|
||||
metadata=self.metadata(),
|
||||
resource={},
|
||||
resource_name="Defender Malware Policy",
|
||||
resource_id="defenderMalwarePolicy",
|
||||
)
|
||||
report.status = "FAIL"
|
||||
report.status_extended = "Common Attachment Types Filter is not enabled."
|
||||
findings.append(report)
|
||||
else:
|
||||
for policy in defender_client.malware_policies:
|
||||
report = CheckReportM365(
|
||||
metadata=self.metadata(),
|
||||
resource=policy,
|
||||
resource_name="Defender Malware Policy",
|
||||
resource_id="defenderMalwarePolicy",
|
||||
)
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"Common Attachment Types Filter is not properly configured in anti-malware policy {policy.identity}."
|
||||
|
||||
if not policy.enable_file_filter:
|
||||
report.status_extended = f"Common Attachment Types Filter is not enabled in anti-malware policy {policy.identity}."
|
||||
break
|
||||
|
||||
if (
|
||||
not policy.is_default
|
||||
and policy.identity in defender_client.malware_rules
|
||||
) or policy.is_default:
|
||||
if (
|
||||
not policy.is_default
|
||||
and defender_client.malware_rules[policy.identity].state.lower()
|
||||
== "enabled"
|
||||
) or policy.is_default:
|
||||
blocked_extensions = [ext.lower() for ext in policy.file_types]
|
||||
missing = [
|
||||
ext
|
||||
for ext in recommended_extensions
|
||||
if ext.lower() not in blocked_extensions
|
||||
]
|
||||
|
||||
if missing:
|
||||
report.status_extended = f"Common Attachment Types Filter is enabled in anti-malware policy {policy.identity}, but the following recommended file types are missing: {', '.join(missing)}."
|
||||
break
|
||||
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"Common Attachment Types Filter is enabled in anti-malware policy {policy.identity}, the policy is enabled and the filter is applied to the recommended file types."
|
||||
|
||||
else:
|
||||
report.status_extended = f"Common Attachment Types Filter is enabled in anti-malware policy {policy.identity}, but the policy is disabled."
|
||||
break
|
||||
|
||||
findings.append(report)
|
||||
|
||||
return findings
|
||||
@@ -22,6 +22,7 @@ class Defender(M365Service):
|
||||
if self.powershell:
|
||||
self.powershell.connect_exchange_online()
|
||||
self.malware_policies = self._get_malware_filter_policy()
|
||||
self.malware_rules = self._get_malware_filter_rule()
|
||||
self.outbound_spam_policies = self._get_outbound_spam_filter_policy()
|
||||
self.outbound_spam_rules = self._get_outbound_spam_filter_rule()
|
||||
self.antiphishing_policies = self._get_antiphising_policy()
|
||||
@@ -50,6 +51,8 @@ class Defender(M365Service):
|
||||
internal_sender_admin_address=policy.get(
|
||||
"InternalSenderAdminAddress", ""
|
||||
),
|
||||
file_types=policy.get("FileTypes", []),
|
||||
is_default=policy.get("IsDefault", False),
|
||||
)
|
||||
)
|
||||
except Exception as error:
|
||||
@@ -58,6 +61,24 @@ class Defender(M365Service):
|
||||
)
|
||||
return malware_policies
|
||||
|
||||
def _get_malware_filter_rule(self):
|
||||
logger.info("Microsoft365 - Getting Defender malware filter rule...")
|
||||
malware_rules = {}
|
||||
try:
|
||||
malware_rule = self.powershell.get_malware_filter_rule()
|
||||
if isinstance(malware_rule, dict):
|
||||
malware_rule = [malware_rule]
|
||||
for rule in malware_rule:
|
||||
if rule:
|
||||
malware_rules[rule.get("Name", "")] = MalwareRule(
|
||||
state=rule.get("State", ""),
|
||||
)
|
||||
except Exception as error:
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
return malware_rules
|
||||
|
||||
def _get_antiphising_policy(self):
|
||||
logger.info("Microsoft365 - Getting Defender antiphishing policy...")
|
||||
antiphishing_policies = {}
|
||||
@@ -222,6 +243,12 @@ class MalwarePolicy(BaseModel):
|
||||
identity: str
|
||||
enable_internal_sender_admin_notifications: bool
|
||||
internal_sender_admin_address: str
|
||||
file_types: list[str]
|
||||
is_default: bool
|
||||
|
||||
|
||||
class MalwareRule(BaseModel):
|
||||
state: str
|
||||
|
||||
|
||||
class AntiphishingPolicy(BaseModel):
|
||||
|
||||
@@ -448,6 +448,18 @@ m365:
|
||||
# Exchange Organization Settings
|
||||
# m365.exchange_organization_mailtips_enabled
|
||||
recommended_mailtips_large_audience_threshold: 25 # maximum number of recipients
|
||||
# Defender Malware Policy Settings
|
||||
# m365.defender_malware_policy_comprehensive_attachments_filter_applied
|
||||
# The recommended list of file extensions to be blocked, this can be changed depending on the organization needs
|
||||
default_recommended_extensions:
|
||||
[
|
||||
"ace", "ani", "apk", "app", "appx", "arj", "bat", "cab", "cmd", "com",
|
||||
"deb", "dex", "dll", "docm", "elf", "exe", "hta", "img", "iso", "jar",
|
||||
"jnlp", "kext", "lha", "lib", "library", "lnk", "lzh", "macho", "msc",
|
||||
"msi", "msix", "msp", "mst", "pif", "ppa", "ppam", "reg", "rev", "scf",
|
||||
"scr", "sct", "sys", "uif", "vb", "vbe", "vbs", "vxd", "wsc", "wsf",
|
||||
"wsh", "xll", "xz", "z"
|
||||
]
|
||||
# Exchange Mailbox Settings
|
||||
# m365.exchange_mailbox_properties_auditing_enabled
|
||||
audit_log_age: 90 # maximum number of days to keep audit logs
|
||||
|
||||
+4
@@ -35,6 +35,8 @@ class Test_defender_malware_policy_common_attachments_filter_enabled:
|
||||
identity="Policy1",
|
||||
enable_internal_sender_admin_notifications=False,
|
||||
internal_sender_admin_address="",
|
||||
file_types=[],
|
||||
is_default=True,
|
||||
),
|
||||
]
|
||||
|
||||
@@ -83,6 +85,8 @@ class Test_defender_malware_policy_common_attachments_filter_enabled:
|
||||
identity="Policy1",
|
||||
enable_internal_sender_admin_notifications=False,
|
||||
internal_sender_admin_address="",
|
||||
file_types=[],
|
||||
is_default=True,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
from unittest import mock
|
||||
|
||||
from prowler.providers.m365.services.defender.defender_service import (
|
||||
MalwarePolicy,
|
||||
MalwareRule,
|
||||
)
|
||||
from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
|
||||
|
||||
|
||||
class Test_defender_malware_policy_comprehensive_attachments_filter_applied:
|
||||
def test_no_policy(self):
|
||||
defender_client = mock.MagicMock()
|
||||
defender_client.audited_tenant = "audited_tenant"
|
||||
defender_client.audited_domain = DOMAIN
|
||||
defender_client.malware_policies = []
|
||||
defender_client.audit_config = {}
|
||||
defender_client.malware_rules = {}
|
||||
|
||||
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_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied.defender_client",
|
||||
new=defender_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.m365.services.defender.defender_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied import (
|
||||
defender_malware_policy_comprehensive_attachments_filter_applied,
|
||||
)
|
||||
|
||||
check = defender_malware_policy_comprehensive_attachments_filter_applied()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Common Attachment Types Filter is not enabled."
|
||||
)
|
||||
assert result[0].resource == {}
|
||||
assert result[0].resource_name == "Defender Malware Policy"
|
||||
assert result[0].resource_id == "defenderMalwarePolicy"
|
||||
assert result[0].location == "global"
|
||||
|
||||
def test_policy_enabled_all_extensions_blocked(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_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied.defender_client",
|
||||
new=defender_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.m365.services.defender.defender_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied import (
|
||||
defender_malware_policy_comprehensive_attachments_filter_applied,
|
||||
)
|
||||
|
||||
valid_extensions = ["exe", "bat", "js"]
|
||||
defender_client.audit_config = {
|
||||
"recommended_blocked_file_types": valid_extensions
|
||||
}
|
||||
defender_client.malware_rules = {"PolicyGood": MalwareRule(state="Enabled")}
|
||||
defender_client.malware_policies = [
|
||||
MalwarePolicy(
|
||||
enable_file_filter=True,
|
||||
identity="PolicyGood",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="admin@example.com",
|
||||
file_types=valid_extensions,
|
||||
is_default=True,
|
||||
)
|
||||
]
|
||||
|
||||
check = defender_malware_policy_comprehensive_attachments_filter_applied()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Common Attachment Types Filter is enabled in anti-malware policy PolicyGood, the policy is enabled and the filter is applied to the recommended file types."
|
||||
)
|
||||
assert result[0].resource == defender_client.malware_policies[0].dict()
|
||||
assert result[0].resource_name == "Defender Malware Policy"
|
||||
assert result[0].resource_id == "defenderMalwarePolicy"
|
||||
assert result[0].location == "global"
|
||||
|
||||
def test_policy_enabled_missing_extensions(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_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied.defender_client",
|
||||
new=defender_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.m365.services.defender.defender_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied import (
|
||||
defender_malware_policy_comprehensive_attachments_filter_applied,
|
||||
)
|
||||
|
||||
defender_client.audit_config = {
|
||||
"recommended_blocked_file_types": ["exe", "bat", "js"]
|
||||
}
|
||||
defender_client.malware_rules = {
|
||||
"PolicyPartial": MalwareRule(state="Enabled")
|
||||
}
|
||||
defender_client.malware_policies = [
|
||||
MalwarePolicy(
|
||||
enable_file_filter=True,
|
||||
identity="PolicyPartial",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="admin@example.com",
|
||||
file_types=["exe"],
|
||||
is_default=True,
|
||||
)
|
||||
]
|
||||
|
||||
check = defender_malware_policy_comprehensive_attachments_filter_applied()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Common Attachment Types Filter is enabled in anti-malware policy PolicyPartial, but the following recommended file types are missing: bat, js."
|
||||
)
|
||||
assert result[0].resource == defender_client.malware_policies[0].dict()
|
||||
assert result[0].resource_name == "Defender Malware Policy"
|
||||
assert result[0].resource_id == "defenderMalwarePolicy"
|
||||
assert result[0].location == "global"
|
||||
|
||||
def test_policy_enabled_but_rule_disabled(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_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied.defender_client",
|
||||
new=defender_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.m365.services.defender.defender_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied import (
|
||||
defender_malware_policy_comprehensive_attachments_filter_applied,
|
||||
)
|
||||
|
||||
valid_extensions = ["exe"]
|
||||
defender_client.audit_config = {
|
||||
"recommended_blocked_file_types": valid_extensions
|
||||
}
|
||||
defender_client.malware_rules = {
|
||||
"PolicyDisabled": MalwareRule(state="Disabled")
|
||||
}
|
||||
defender_client.malware_policies = [
|
||||
MalwarePolicy(
|
||||
enable_file_filter=True,
|
||||
identity="PolicyDisabled",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="admin@example.com",
|
||||
file_types=valid_extensions,
|
||||
is_default=False,
|
||||
)
|
||||
]
|
||||
|
||||
check = defender_malware_policy_comprehensive_attachments_filter_applied()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Common Attachment Types Filter is enabled in anti-malware policy PolicyDisabled, but the policy is disabled."
|
||||
)
|
||||
assert result[0].resource == defender_client.malware_policies[0].dict()
|
||||
assert result[0].resource_name == "Defender Malware Policy"
|
||||
assert result[0].resource_id == "defenderMalwarePolicy"
|
||||
assert result[0].location == "global"
|
||||
|
||||
def test_policy_enabled_but_no_rule_and_not_default(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_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied.defender_client",
|
||||
new=defender_client,
|
||||
),
|
||||
):
|
||||
from prowler.providers.m365.services.defender.defender_malware_policy_comprehensive_attachments_filter_applied.defender_malware_policy_comprehensive_attachments_filter_applied import (
|
||||
defender_malware_policy_comprehensive_attachments_filter_applied,
|
||||
)
|
||||
|
||||
valid_extensions = ["exe"]
|
||||
defender_client.audit_config = {
|
||||
"recommended_blocked_file_types": valid_extensions
|
||||
}
|
||||
defender_client.malware_rules = {}
|
||||
defender_client.malware_policies = [
|
||||
MalwarePolicy(
|
||||
enable_file_filter=True,
|
||||
identity="PolicyNoRule",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="admin@example.com",
|
||||
file_types=valid_extensions,
|
||||
is_default=False,
|
||||
)
|
||||
]
|
||||
|
||||
check = defender_malware_policy_comprehensive_attachments_filter_applied()
|
||||
result = check.execute()
|
||||
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "Common Attachment Types Filter is not properly configured in anti-malware policy PolicyNoRule."
|
||||
)
|
||||
assert result[0].resource == defender_client.malware_policies[0].dict()
|
||||
assert result[0].resource_name == "Defender Malware Policy"
|
||||
assert result[0].resource_id == "defenderMalwarePolicy"
|
||||
assert result[0].location == "global"
|
||||
+6
@@ -35,6 +35,8 @@ class Test_defender_malware_policy_notifications_internal_users_malware_enabled:
|
||||
identity="Default",
|
||||
enable_internal_sender_admin_notifications=False,
|
||||
internal_sender_admin_address="",
|
||||
file_types=[],
|
||||
is_default=True,
|
||||
)
|
||||
]
|
||||
|
||||
@@ -85,6 +87,8 @@ class Test_defender_malware_policy_notifications_internal_users_malware_enabled:
|
||||
identity="Default",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="",
|
||||
file_types=[],
|
||||
is_default=True,
|
||||
)
|
||||
]
|
||||
|
||||
@@ -135,6 +139,8 @@ class Test_defender_malware_policy_notifications_internal_users_malware_enabled:
|
||||
identity="Default",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="security@example.com",
|
||||
file_types=[],
|
||||
is_default=True,
|
||||
)
|
||||
]
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ from prowler.providers.m365.services.defender.defender_service import (
|
||||
DefenderInboundSpamPolicy,
|
||||
DkimConfig,
|
||||
MalwarePolicy,
|
||||
MalwareRule,
|
||||
OutboundSpamPolicy,
|
||||
OutboundSpamRule,
|
||||
)
|
||||
@@ -23,16 +24,27 @@ def mock_defender_get_malware_filter_policy(_):
|
||||
identity="Policy1",
|
||||
enable_internal_sender_admin_notifications=False,
|
||||
internal_sender_admin_address="",
|
||||
file_types=[],
|
||||
is_default=True,
|
||||
),
|
||||
MalwarePolicy(
|
||||
enable_file_filter=True,
|
||||
identity="Policy2",
|
||||
enable_internal_sender_admin_notifications=True,
|
||||
internal_sender_admin_address="security@example.com",
|
||||
file_types=["exe", "zip"],
|
||||
is_default=False,
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
def mock_defender_get_malware_filter_rule(_):
|
||||
return {
|
||||
"Policy1": MalwareRule(state="Enabled"),
|
||||
"Policy2": MalwareRule(state="Disabled"),
|
||||
}
|
||||
|
||||
|
||||
def mock_defender_get_antiphising_policy(_):
|
||||
return {
|
||||
"Policy1": AntiphishingPolicy(
|
||||
@@ -167,6 +179,10 @@ class Test_Defender_Service:
|
||||
malware_policies[0].enable_internal_sender_admin_notifications is False
|
||||
)
|
||||
assert malware_policies[0].internal_sender_admin_address == ""
|
||||
assert malware_policies[0].enable_file_filter is False
|
||||
assert malware_policies[0].identity == "Policy1"
|
||||
assert malware_policies[0].file_types == []
|
||||
assert malware_policies[0].is_default is True
|
||||
assert malware_policies[1].enable_file_filter is True
|
||||
assert malware_policies[1].identity == "Policy2"
|
||||
assert (
|
||||
@@ -176,6 +192,28 @@ class Test_Defender_Service:
|
||||
malware_policies[1].internal_sender_admin_address
|
||||
== "security@example.com"
|
||||
)
|
||||
assert malware_policies[1].file_types == ["exe", "zip"]
|
||||
assert malware_policies[1].is_default is False
|
||||
defender_client.powershell.close()
|
||||
|
||||
@patch(
|
||||
"prowler.providers.m365.services.defender.defender_service.Defender._get_malware_filter_rule",
|
||||
new=mock_defender_get_malware_filter_rule,
|
||||
)
|
||||
def test__get_malware_filter_rule(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)
|
||||
)
|
||||
)
|
||||
malware_rules = defender_client.malware_rules
|
||||
assert malware_rules["Policy1"].state == "Enabled"
|
||||
assert malware_rules["Policy2"].state == "Disabled"
|
||||
defender_client.powershell.close()
|
||||
|
||||
@patch(
|
||||
|
||||
Reference in New Issue
Block a user