diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index a3edc2e94a..9a73fdf02f 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -10,6 +10,7 @@ All notable changes to the **Prowler SDK** are documented in this file. - Add check for unused Service Accounts in GCP [(#7419)](https://github.com/prowler-cloud/prowler/pull/7419). - Support CLOUDSDK_AUTH_ACCESS_TOKEN in GCP [(#7495)](https://github.com/prowler-cloud/prowler/pull/7495). - Add Powershell to Microsoft365 [(#7331)](https://github.com/prowler-cloud/prowler/pull/7331) +- Add new check `teams_email_sending_to_channel_disabled` [(#7533)](https://github.com/prowler-cloud/prowler/pull/7533) ### Fixed diff --git a/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/__init__.py b/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled.metadata.json b/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled.metadata.json new file mode 100644 index 0000000000..ddee3091c7 --- /dev/null +++ b/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled.metadata.json @@ -0,0 +1,30 @@ +{ + "Provider": "m365", + "CheckID": "teams_email_sending_to_channel_disabled", + "CheckTitle": "Ensure users are not be able to email the channel directly.", + "CheckType": [], + "ServiceName": "teams", + "SubServiceName": "", + "ResourceIdTemplate": "", + "Severity": "high", + "ResourceType": "Teams Settings", + "Description": "Ensure users can not send emails to channel email addresses.", + "Risk": "Allowing users to send emails to Teams channel email addresses introduces a security risk, as these addresses are outside the tenant’s domain and lack proper security controls. This creates a potential attack vector where threat actors could exploit the channel email to deliver malicious content or spam.", + "RelatedUrl": "https://learn.microsoft.com/en-us/powershell/module/teams/get-csteamsclientconfiguration?view=teams-ps", + "Remediation": { + "Code": { + "CLI": "Set-CsTeamsClientConfiguration -Identity Global -AllowEmailIntoChannel $false", + "NativeIaC": "", + "Other": "1. Navigate to Microsoft Teams admin center https://admin.teams.microsoft.com. 2. Click to expand Teams select Teams settings. 3. Under email integration set Users can send emails to a channel email address to Off.", + "Terraform": "" + }, + "Recommendation": { + "Text": "Disable the ability for users to send emails to Teams channel email addresses to reduce the risk of external abuse and enhance control over organizational communications.", + "Url": "https://learn.microsoft.com/en-us/powershell/module/teams/get-csteamsclientconfiguration?view=teams-ps" + } + }, + "Categories": [], + "DependsOn": [], + "RelatedTo": [], + "Notes": "" +} diff --git a/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled.py b/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled.py new file mode 100644 index 0000000000..f5a96266c3 --- /dev/null +++ b/prowler/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled.py @@ -0,0 +1,41 @@ +from typing import List + +from prowler.lib.check.models import Check, CheckReportM365 +from prowler.providers.m365.services.teams.teams_client import teams_client + + +class teams_email_sending_to_channel_disabled(Check): + """Check if + + Attributes: + metadata: Metadata associated with the check (inherited from Check). + """ + + def execute(self) -> List[CheckReportM365]: + """Execute the check for + + This method checks if + + Returns: + List[CheckReportM365]: A list of reports containing the result of the check. + """ + findings = [] + teams_settings = teams_client.teams_settings + report = CheckReportM365( + metadata=self.metadata(), + resource=teams_settings if teams_settings else {}, + resource_name="Teams Settings", + resource_id="teamsSettings", + ) + report.status = "FAIL" + report.status_extended = "Users can send emails to channel email addresses." + + if teams_settings and not teams_settings.allow_email_into_channel: + report.status = "PASS" + report.status_extended = ( + "Users can not send emails to channel email addresses." + ) + + findings.append(report) + + return findings diff --git a/prowler/providers/m365/services/teams/teams_service.py b/prowler/providers/m365/services/teams/teams_service.py index 1415b6118b..71474ce724 100644 --- a/prowler/providers/m365/services/teams/teams_service.py +++ b/prowler/providers/m365/services/teams/teams_service.py @@ -14,8 +14,9 @@ class Teams(M365Service): def _get_teams_client_configuration(self): logger.info("M365 - Getting Teams settings...") - settings = self.powershell.get_teams_settings() + teams_settings = None try: + settings = self.powershell.get_teams_settings() teams_settings = TeamsSettings( cloud_storage_settings=CloudStorageSettings( allow_box=settings.get("AllowBox", True), @@ -23,7 +24,8 @@ class Teams(M365Service): allow_egnyte=settings.get("AllowEgnyte", True), allow_google_drive=settings.get("AllowGoogleDrive", True), allow_share_file=settings.get("AllowShareFile", True), - ) + ), + allow_email_into_channel=settings.get("AllowEmailIntoChannel", True), ) except Exception as error: @@ -43,3 +45,4 @@ class CloudStorageSettings(BaseModel): class TeamsSettings(BaseModel): cloud_storage_settings: CloudStorageSettings + allow_email_into_channel: bool = True diff --git a/tests/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled_test.py b/tests/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled_test.py new file mode 100644 index 0000000000..7ee0a6a61d --- /dev/null +++ b/tests/providers/m365/services/teams/teams_email_sending_to_channel_disabled/teams_email_sending_to_channel_disabled_test.py @@ -0,0 +1,105 @@ +from unittest import mock + +from tests.providers.m365.m365_fixtures import DOMAIN, set_mocked_m365_provider + + +class Test_teams_email_sending_to_channel_disabled: + def test_email_sending_to_channel_no_restricted(self): + teams_client = mock.MagicMock() + teams_client.audited_tenant = "audited_tenant" + teams_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_microsoft_teams" + ), + mock.patch( + "prowler.providers.m365.services.teams.teams_email_sending_to_channel_disabled.teams_email_sending_to_channel_disabled.teams_client", + new=teams_client, + ), + ): + from prowler.providers.m365.services.teams.teams_email_sending_to_channel_disabled.teams_email_sending_to_channel_disabled import ( + teams_email_sending_to_channel_disabled, + ) + from prowler.providers.m365.services.teams.teams_service import ( + CloudStorageSettings, + TeamsSettings, + ) + + teams_client.teams_settings = TeamsSettings( + cloud_storage_settings=CloudStorageSettings( + allow_box=True, + allow_drop_box=True, + allow_egnyte=True, + allow_google_drive=True, + allow_share_file=True, + ), + allow_email_into_channel=True, + ) + + check = teams_email_sending_to_channel_disabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "FAIL" + assert ( + result[0].status_extended + == "Users can send emails to channel email addresses." + ) + assert result[0].resource == teams_client.teams_settings.dict() + assert result[0].resource_name == "Teams Settings" + assert result[0].resource_id == "teamsSettings" + assert result[0].location == "global" + + def test_email_sending_to_channel_restricted(self): + teams_client = mock.MagicMock() + teams_client.audited_tenant = "audited_tenant" + teams_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_microsoft_teams" + ), + mock.patch( + "prowler.providers.m365.services.teams.teams_email_sending_to_channel_disabled.teams_email_sending_to_channel_disabled.teams_client", + new=teams_client, + ), + ): + from prowler.providers.m365.services.teams.teams_email_sending_to_channel_disabled.teams_email_sending_to_channel_disabled import ( + teams_email_sending_to_channel_disabled, + ) + from prowler.providers.m365.services.teams.teams_service import ( + CloudStorageSettings, + TeamsSettings, + ) + + teams_client.teams_settings = TeamsSettings( + cloud_storage_settings=CloudStorageSettings( + allow_box=True, + allow_drop_box=True, + allow_egnyte=True, + allow_google_drive=True, + allow_share_file=True, + ), + allow_email_into_channel=False, + ) + + check = teams_email_sending_to_channel_disabled() + result = check.execute() + assert len(result) == 1 + assert result[0].status == "PASS" + assert ( + result[0].status_extended + == "Users can not send emails to channel email addresses." + ) + assert result[0].resource == teams_client.teams_settings.dict() + assert result[0].resource_name == "Teams Settings" + assert result[0].resource_id == "teamsSettings" + assert result[0].location == "global"