Back to Checks
m365

Transport rule does not whitelist any domains

exchange_transport_rules_whitelist_disabled
Service: exchangeSeverity: high
OfficialBuilt-inVerified
Categories:email-securitye3
Resource Type:NotDefined

Microsoft 365 Exchange Online mail flow rules that whitelist specific sender domains by forcing SCL to -1 (skip spam filtering) on matching messages

Risk

Domain-based whitelisting skips anti-spam/phish analysis, allowing spoofed or compromised senders to reach the Inbox. This increases targeted phishing, BEC, and credential theft, enabling unauthorized access and data exfiltration, degrading confidentiality and integrity.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler m365 --checks exchange_transport_rules_whitelist_disabled

Recommendation

Avoid blanket whitelisting. Do not set SCL to -1 based solely on sender domain.

  • Prefer controlled allow mechanisms with review/expiry; keep anti-spam/phish active
  • If exceptions are unavoidable, apply least privilege: add strong conditions (auth results, known source IPs), narrow scope, time-bound, and monitor

Remediation

CLI

Set-TransportRule -Identity <RuleName> -SetSCL 0

Other

1Open the Exchange admin center: https://admin.exchange.microsoft.com
2Go to Mail flow > Rules
3Edit any rule that has: condition "The sender domain is" AND action "Set the spam confidence level (SCL) = Bypass spam filtering"
4In Do the following, change "Set the spam confidence level (SCL)" from Bypass spam filtering to 0 (or remove the action)
5Click Save

Check Code

from typing import List

from prowler.lib.check.models import Check, CheckReportM365
from prowler.providers.m365.services.exchange.exchange_client import exchange_client


class exchange_transport_rules_whitelist_disabled(Check):
    """
    Check to ensure that no mail transport rules whitelist specific domains.

    Attributes:
        metadata: Metadata associated with the check (inherited from Check).
    """

    def execute(self) -> List[CheckReportM365]:
        """
        Execute the check to validate that no transport rules whitelist specific domains.

        This method retrieves all transport rules from the Exchange service and evaluates
        whether any of them whitelist specific domains. A report is generated for each
        transport rule.

        Returns:
            List[CheckReportM365]: A list of findings with the status of each transport rule.
        """
        findings = []

        for rule in exchange_client.transport_rules:
            report = CheckReportM365(
                metadata=self.metadata(),
                resource=rule,
                resource_name=rule.name,
                resource_id="ExchangeTransportRule",
            )

            report.status = "PASS"
            report.status_extended = (
                f"Transport rule {rule.name} does not whitelist any domains."
            )

            if rule.sender_domain_is and rule.scl == -1:
                report.status = "FAIL"
                report.status_extended = f"Transport rule {rule.name} whitelists domains: {', '.join(rule.sender_domain_is)}."

            findings.append(report)

        return findings