feat(exchange): make exchange_user_mailbox_auditing_enabled check configurable (#7662)

Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
This commit is contained in:
Daniel Barranquero
2025-05-05 21:16:41 +02:00
committed by GitHub
parent 7eec60f4d9
commit 6b0d73d7f9
7 changed files with 55 additions and 42 deletions
+1
View File
@@ -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)
- Modified check `exchange_mailbox_properties_auditing_enabled` to make it configurable [(#7662)](https://github.com/prowler-cloud/prowler/pull/7662)
### Fixed
+6 -3
View File
@@ -484,10 +484,10 @@ kubernetes:
# M365 Configuration
m365:
# Entra Conditional Access Policy
# Entra
# m365.entra_admin_users_sign_in_frequency_enabled
sign_in_frequency: 4 # 4 hours
# Teams Settings
# Teams
# m365.teams_external_file_sharing_restricted
allowed_cloud_storage_services:
[
@@ -497,6 +497,9 @@ m365:
#"allow_google_drive",
#"allow_share_file",
]
# Exchange Organization Settings
# Exchange
# m365.exchange_organization_mailtips_enabled
recommended_mailtips_large_audience_threshold: 25 # maximum number of recipients
# m365.exchange_mailbox_properties_auditing_enabled
# Maximum number of days to keep audit logs
audit_log_age: 90
@@ -1,14 +1,14 @@
{
"Provider": "m365",
"CheckID": "exchange_mailbox_properties_auditing_e3_enabled",
"CheckTitle": "Ensure mailbox auditing for E3 users is enabled.",
"CheckID": "exchange_user_mailbox_auditing_enabled",
"CheckTitle": "Ensure mailbox auditing is enabled for all user mailboxes.",
"CheckType": [],
"ServiceName": "exchange",
"SubServiceName": "",
"ResourceIdTemplate": "",
"Severity": "high",
"ResourceType": "Exchange Mailboxes Properties",
"Description": "Ensure mailbox auditing is enabled for all E3-licensed user mailboxes, including the configuration of audit actions for owners, delegates, and admins beyond the Microsoft defaults.",
"Description": "Ensure mailbox auditing is enabled for all user mailboxes, including the configuration of audit actions for owners, delegates, and admins beyond the Microsoft defaults. The difference between both subscription is the log age so this parameter is configurable and users can set it to their subscription needs.",
"Risk": "If auditing is not properly enabled and configured, critical mailbox actions may go unrecorded, reducing the ability to investigate incidents, enforce compliance, or detect malicious behavior.",
"RelatedUrl": "https://learn.microsoft.com/en-us/purview/audit-mailboxes?view=o365-worldwide",
"Remediation": {
@@ -19,7 +19,7 @@
"Terraform": ""
},
"Recommendation": {
"Text": "Enable mailbox auditing for all E3 user mailboxes and configure auditing for key mailbox actions for owners, delegates, and admins.",
"Text": "Enable mailbox auditing for all user mailboxes and configure auditing for key mailbox actions for owners, delegates, and admins.",
"Url": "https://learn.microsoft.com/en-us/purview/audit-mailboxes?view=o365-worldwide"
}
},
@@ -9,9 +9,9 @@ from prowler.providers.m365.services.exchange.exchange_service import (
)
class exchange_mailbox_properties_auditing_e3_enabled(Check):
class exchange_user_mailbox_auditing_enabled(Check):
"""
Check to ensure that mailbox auditing properties are enabled and properly configured.
Check to ensure mailbox auditing is enabled for all user mailboxes.
Attributes:
metadata: Metadata associated with the check (inherited from Check).
@@ -19,7 +19,7 @@ class exchange_mailbox_properties_auditing_e3_enabled(Check):
def execute(self) -> List[CheckReportM365]:
"""
Execute the check to validate that mailbox auditing properties are enabled and properly configured.
Execute the check to validate that mailbox auditing is enabled for all user mailboxes.
This method retrieves all mailbox audit properties from the Exchange service and evaluates
whether auditing is enabled and correctly configured for each mailbox. A report is generated
@@ -57,17 +57,15 @@ class exchange_mailbox_properties_auditing_e3_enabled(Check):
and required_delegate.issubset(audit_delegate)
and required_owner.issubset(audit_owner)
):
# The limit for E3 is 90 days, but we check >= 90 because E5 users can set it to more than 90 days
if mailbox.audit_log_age >= 90:
if mailbox.audit_log_age >= exchange_client.audit_config.get(
"audit_log_age", 90
):
report.status = "PASS"
report.status_extended = f"Mailbox Audit Properties for Mailbox {mailbox.name} is enabled and properly configured."
report.status_extended = f"Mailbox Audit Properties for Mailbox {mailbox.name} is enabled with an audit log age of {mailbox.audit_log_age} days."
else:
report.status_extended = f"Mailbox Audit Properties for Mailbox {mailbox.name} is enabled and properly configured but the audit log age is less than 90 days."
report.status_extended = f"Mailbox Audit Properties for Mailbox {mailbox.name} is enabled but the audit log age is less than {exchange_client.audit_config.get('audit_log_age', 90)} days ({mailbox.audit_log_age} days)."
else:
report.status_extended = (
f"Mailbox Audit Properties for Mailbox {mailbox.name} is enabled but not properly configured. "
f"Missing audit actions may exist."
)
report.status_extended = f"Mailbox Audit Properties for Mailbox {mailbox.name} is enabled but without all audit actions configured."
findings.append(report)
+3
View File
@@ -448,3 +448,6 @@ m365:
# Exchange Organization Settings
# m365.exchange_organization_mailtips_enabled
recommended_mailtips_large_audience_threshold: 25 # maximum number of recipients
# Exchange Mailbox Settings
# m365.exchange_mailbox_properties_auditing_enabled
audit_log_age: 90 # maximum number of days to keep audit logs
@@ -9,7 +9,7 @@ from prowler.providers.m365.services.exchange.exchange_service import (
from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
class Test_exchange_mailbox_properties_auditing_e3_enabled:
class Test_exchange_user_mailbox_auditing_enabled:
def test_no_auditing_mailboxes(self):
exchange_client = mock.MagicMock()
exchange_client.audited_tenant = "audited_tenant"
@@ -24,17 +24,17 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled.exchange_client",
"prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled import (
exchange_mailbox_properties_auditing_e3_enabled,
from prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled import (
exchange_user_mailbox_auditing_enabled,
)
exchange_client.mailbox_audit_properties = []
check = exchange_mailbox_properties_auditing_e3_enabled()
check = exchange_user_mailbox_auditing_enabled()
result = check.execute()
assert len(result) == 0
@@ -53,14 +53,16 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled.exchange_client",
"prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled import (
exchange_mailbox_properties_auditing_e3_enabled,
from prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled import (
exchange_user_mailbox_auditing_enabled,
)
exchange_client.audit_config = {"audit_log_age": 180}
exchange_client.mailbox_audit_properties = [
MailboxAuditProperties(
name="User1",
@@ -73,14 +75,14 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
)
]
check = exchange_mailbox_properties_auditing_e3_enabled()
check = exchange_user_mailbox_auditing_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "Mailbox Audit Properties for Mailbox User1 is enabled and properly configured."
== "Mailbox Audit Properties for Mailbox User1 is enabled with an audit log age of 180 days."
)
assert result[0].resource_name == "User1"
assert result[0].resource_id == "User1"
@@ -103,14 +105,16 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled.exchange_client",
"prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled import (
exchange_mailbox_properties_auditing_e3_enabled,
from prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled import (
exchange_user_mailbox_auditing_enabled,
)
exchange_client.audit_config = {"audit_log_age": 90}
exchange_client.mailbox_audit_properties = [
MailboxAuditProperties(
name="User2",
@@ -123,14 +127,14 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
)
]
check = exchange_mailbox_properties_auditing_e3_enabled()
check = exchange_user_mailbox_auditing_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Mailbox Audit Properties for Mailbox User2 is enabled but not properly configured. Missing audit actions may exist."
== "Mailbox Audit Properties for Mailbox User2 is enabled but without all audit actions configured."
)
assert result[0].resource_name == "User2"
assert result[0].resource_id == "User2"
@@ -153,14 +157,16 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled.exchange_client",
"prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled import (
exchange_mailbox_properties_auditing_e3_enabled,
from prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled import (
exchange_user_mailbox_auditing_enabled,
)
exchange_client.audit_config = {"audit_log_age": 90}
exchange_client.mailbox_audit_properties = [
MailboxAuditProperties(
name="User3",
@@ -173,7 +179,7 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
)
]
check = exchange_mailbox_properties_auditing_e3_enabled()
check = exchange_user_mailbox_auditing_enabled()
result = check.execute()
assert len(result) == 1
@@ -203,14 +209,16 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
mock.patch(
"prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled.exchange_client",
"prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_properties_auditing_e3_enabled.exchange_mailbox_properties_auditing_e3_enabled import (
exchange_mailbox_properties_auditing_e3_enabled,
from prowler.providers.m365.services.exchange.exchange_user_mailbox_auditing_enabled.exchange_user_mailbox_auditing_enabled import (
exchange_user_mailbox_auditing_enabled,
)
exchange_client.audit_config = {"audit_log_age": 90}
exchange_client.mailbox_audit_properties = [
MailboxAuditProperties(
name="User4",
@@ -223,14 +231,14 @@ class Test_exchange_mailbox_properties_auditing_e3_enabled:
)
]
check = exchange_mailbox_properties_auditing_e3_enabled()
check = exchange_user_mailbox_auditing_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Mailbox Audit Properties for Mailbox User4 is enabled and properly configured but the audit log age is less than 90 days."
== "Mailbox Audit Properties for Mailbox User4 is enabled but the audit log age is less than 90 days (30 days)."
)
assert result[0].resource_name == "User4"
assert result[0].resource_id == "User4"