feat(exchange): add new check exchange_mailbox_audit_bypass_disabled (#7418)

Co-authored-by: HugoPBrito <hugopbrit@gmail.com>
Co-authored-by: MrCloudSec <hello@mistercloudsec.com>
This commit is contained in:
Daniel Barranquero
2025-04-16 20:06:32 +02:00
committed by Pepe Fagoaga
parent 311c9a41ff
commit 00e33d39bb
14 changed files with 421 additions and 100 deletions
@@ -0,0 +1,175 @@
from unittest import mock
from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
class Test_exchange_mailbox_audit_bypass_disabled:
def test_no_mailboxes(self):
exchange_client = mock.MagicMock()
exchange_client.audited_tenant = "audited_tenant"
exchange_client.audited_domain = DOMAIN
exchange_client.mailboxes_config = []
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.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled import (
exchange_mailbox_audit_bypass_disabled,
)
check = exchange_mailbox_audit_bypass_disabled()
result = check.execute()
assert len(result) == 0
def test_audit_bypass_disabled_and_enabled(self):
exchange_client = mock.MagicMock()
exchange_client.audited_tenant = "audited_tenant"
exchange_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.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled import (
exchange_mailbox_audit_bypass_disabled,
)
from prowler.providers.m365.services.exchange.exchange_service import (
MailboxAuditConfig,
)
exchange_client.mailboxes_config = [
MailboxAuditConfig(name="test", id="test", audit_bypass_enabled=True),
MailboxAuditConfig(
name="test2", id="test2", audit_bypass_enabled=False
),
]
check = exchange_mailbox_audit_bypass_disabled()
result = check.execute()
assert len(result) == 2
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Exchange mailbox auditing is bypassed and not enabled for mailbox: test."
)
assert result[0].resource == exchange_client.mailboxes_config[0].dict()
assert result[0].resource_name == "test"
assert result[0].resource_id == "test"
assert result[0].location == "global"
assert result[1].status == "PASS"
assert (
result[1].status_extended
== "Exchange mailbox auditing is enabled for mailbox: test2."
)
assert result[1].resource == exchange_client.mailboxes_config[1].dict()
assert result[1].resource_name == "test2"
assert result[1].resource_id == "test2"
assert result[1].location == "global"
def test_audit_bypass_enabled(self):
exchange_client = mock.MagicMock()
exchange_client.audited_tenant = "audited_tenant"
exchange_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.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled import (
exchange_mailbox_audit_bypass_disabled,
)
from prowler.providers.m365.services.exchange.exchange_service import (
MailboxAuditConfig,
)
exchange_client.mailboxes_config = [
MailboxAuditConfig(name="test", id="test", audit_bypass_enabled=True),
]
check = exchange_mailbox_audit_bypass_disabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== "Exchange mailbox auditing is bypassed and not enabled for mailbox: test."
)
assert result[0].resource == exchange_client.mailboxes_config[0].dict()
assert result[0].resource_name == "test"
assert result[0].resource_id == "test"
assert result[0].location == "global"
def test_audit_bypass_disabled(self):
exchange_client = mock.MagicMock()
exchange_client.audited_tenant = "audited_tenant"
exchange_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.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled.exchange_client",
new=exchange_client,
),
):
from prowler.providers.m365.services.exchange.exchange_mailbox_audit_bypass_disabled.exchange_mailbox_audit_bypass_disabled import (
exchange_mailbox_audit_bypass_disabled,
)
from prowler.providers.m365.services.exchange.exchange_service import (
MailboxAuditConfig,
)
exchange_client.mailboxes_config = [
MailboxAuditConfig(name="test", id="test", audit_bypass_enabled=False),
]
check = exchange_mailbox_audit_bypass_disabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== "Exchange mailbox auditing is enabled for mailbox: test."
)
assert result[0].resource == exchange_client.mailboxes_config[0].dict()
assert result[0].resource_name == "test"
assert result[0].resource_id == "test"
assert result[0].location == "global"
@@ -4,6 +4,7 @@ from unittest.mock import patch
from prowler.providers.m365.models import M365IdentityInfo
from prowler.providers.m365.services.exchange.exchange_service import (
Exchange,
MailboxAuditConfig,
Organization,
)
from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider
@@ -13,6 +14,13 @@ def mock_exchange_get_organization_config(_):
return Organization(audit_disabled=True, name="test", guid="test")
def mock_exchange_get_mailbox_audit_config(_):
return [
MailboxAuditConfig(name="test", id="test", audit_bypass_enabled=False),
MailboxAuditConfig(name="test2", id="test2", audit_bypass_enabled=True),
]
class Test_Exchange_Service:
def test_get_client(self):
with (
@@ -50,3 +58,29 @@ class Test_Exchange_Service:
assert organization_config.audit_disabled is True
exchange_client.powershell.close()
@patch(
"prowler.providers.m365.services.exchange.exchange_service.Exchange._get_mailbox_audit_config",
new=mock_exchange_get_mailbox_audit_config,
)
def test_get_mailbox_audit_config(self):
with (
mock.patch(
"prowler.providers.m365.lib.powershell.m365_powershell.M365PowerShell.connect_exchange_online"
),
):
exchange_client = Exchange(
set_mocked_m365_provider(
identity=M365IdentityInfo(tenant_domain=DOMAIN)
)
)
mailbox_audit_config = exchange_client.mailboxes_config
assert len(mailbox_audit_config) == 2
assert mailbox_audit_config[0].name == "test"
assert mailbox_audit_config[0].id == "test"
assert mailbox_audit_config[0].audit_bypass_enabled is False
assert mailbox_audit_config[1].name == "test2"
assert mailbox_audit_config[1].id == "test2"
assert mailbox_audit_config[1].audit_bypass_enabled is True
exchange_client.powershell.close()