Back to Checks
azure

Security contact has attack path email notifications enabled at or above the configured minimum risk level

defender_attack_path_notifications_properly_configured
Service: defenderSeverity: high
OfficialBuilt-inVerified
Categories:logging
Resource Type:microsoft.resources/subscriptions

Microsoft Defender for Cloud attack path email notifications are configured per subscription with a defined minimal risk level, and the setting is present and meets the required threshold.

Risk

Without alerts on exploitable attack paths, security teams lose visibility, enabling lateral movement, privilege escalation, and data exfiltration before containment, degrading confidentiality, integrity, and availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks defender_attack_path_notifications_properly_configured

Recommendation

Enable and maintain attack path notifications with a minimal risk level at or above your tolerance (e.g., High). Send to monitored, role-based recipients. Apply defense in depth by integrating alerts with central monitoring and automation for prompt triage.

Remediation

CLI

az rest --method put --uri https://management.azure.com/subscriptions/<SUBSCRIPTION_ID>/providers/Microsoft.Security/securityContacts/default?api-version=2020-01-01-preview --body '{"properties":{"emails":"admin@example.com","attackPathNotifications":{"state":"On","minimalRiskLevel":"Low"}}}'

Terraform

# Enable attack path email notifications at minimal risk level
resource "azapi_resource" "<example_resource_name>" {
  type = "Microsoft.Security/securityContacts@2020-01-01-preview"
  name = "default"
  body = jsonencode({
    properties = {
      emails = "admin@example.com"
      attackPathNotifications = {
        state = "On"              # CRITICAL: enables attack path email notifications
        minimalRiskLevel = "Low"  # CRITICAL: sets minimal risk level to pass the check
      }
    }
  })
}

NativeIaC

// Enable attack path email notifications at minimal risk level
resource securityContact 'Microsoft.Security/securityContacts@2020-01-01-preview' = {
  name: 'default'
  properties: {
    emails: 'admin@example.com'
    attackPathNotifications: {
      state: 'On'              // CRITICAL: enables attack path email notifications
      minimalRiskLevel: 'Low'  // CRITICAL: sets minimal risk level to pass the check
    }
  }
}

Other

1In Azure Portal, go to Microsoft Defender for Cloud > Environment settings
2Select the target subscription
3Open Email notifications
4Enable "Notify about attack paths with the following risk level (or higher)"
5Set Risk level to Low (or your configured minimum)
6Click Save

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.defender.defender_client import defender_client


class defender_attack_path_notifications_properly_configured(Check):
    """
    Ensure that email notifications for attack paths are enabled.

    This check evaluates whether Microsoft Defender for Cloud is configured to send email notifications for attack paths in each Azure subscription.
    - PASS: Notifications are enabled for attack paths with a risk level set (not None) and equal or higher than the configured minimum.
    - FAIL: Notifications are not enabled for attack paths in the subscription or the risk level is too low.
    """

    def execute(self) -> list[Check_Report_Azure]:
        findings = []

        # Get the minimal risk level from config, default to 'High'
        risk_levels = ["Low", "Medium", "High", "Critical"]
        min_risk_level = defender_client.audit_config.get(
            "defender_attack_path_minimal_risk_level", "High"
        )
        if min_risk_level not in risk_levels:
            min_risk_level = "High"
        min_risk_index = risk_levels.index(min_risk_level)

        for (
            subscription_id,
            security_contact_configurations,
        ) in defender_client.security_contact_configurations.items():
            subscription_name = defender_client.subscriptions.get(
                subscription_id, subscription_id
            )
            for contact_configuration in security_contact_configurations.values():
                report = Check_Report_Azure(
                    metadata=self.metadata(), resource=contact_configuration
                )
                report.resource_name = (
                    contact_configuration.name
                    if contact_configuration.name
                    else "Security Contact"
                )
                report.subscription = subscription_id
                actual_risk_level = getattr(
                    contact_configuration, "attack_path_minimal_risk_level", None
                )
                if not actual_risk_level or actual_risk_level not in risk_levels:
                    report.status = "FAIL"
                    report.status_extended = f"Attack path notifications are not enabled in subscription {subscription_name} ({subscription_id}) for security contact {contact_configuration.name}."
                else:
                    actual_risk_index = risk_levels.index(actual_risk_level)
                    if actual_risk_index <= min_risk_index:
                        report.status = "PASS"
                        report.status_extended = f"Attack path notifications are enabled with minimal risk level {actual_risk_level} in subscription {subscription_name} ({subscription_id}) for security contact {contact_configuration.name}."
                    else:
                        report.status = "FAIL"
                        report.status_extended = f"Attack path notifications are enabled with minimal risk level {actual_risk_level} in subscription {subscription_name} ({subscription_id}) for security contact {contact_configuration.name}."
                findings.append(report)

        return findings