Back to Checks
azure

Network security group does not allow inbound UDP from the Internet

network_udp_internet_access_restricted
Service: networkSeverity: high
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:microsoft.network/networksecuritygroups

Azure NSG rules are assessed for inbound UDP exposure to the public Internet (e.g., 0.0.0.0/0, *, Internet). The finding identifies allow rules that permit unsolicited UDP traffic from any external source to attached resources.

Prowler logoProwlerprowler-provider-azure

Risk

Publicly reachable UDP services enable DDoS reflection/amplification, exhausting bandwidth and compute and degrading availability for workloads and networks. Open services (DNS, NTP, SSDP, SNMP, CLDAP) can be abused with spoofed traffic, turning endpoints into amplifiers and disrupting adjacent resources.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks network_udp_internet_access_restricted

Recommendation

Apply least privilege on NSG rules:

  • Deny Internet UDP inbound by default
  • Allow only required sources/ports
  • Prefer private access (VNets, private endpoints, VPN/ExpressRoute)
  • Use defense in depth with Azure Firewall and DDoS Protection
  • Monitor and disable or rate-limit unnecessary UDP services

Remediation

CLI

az network nsg rule update --resource-group <RESOURCE_GROUP> --nsg-name <NSG_NAME> --name <RULE_NAME> --access Deny

Terraform

# Modify the existing NSG rule to deny UDP from the Internet
resource "azurerm_network_security_rule" "<example_resource_name>" {
  name                        = "<example_resource_name>"  # existing rule name
  resource_group_name         = "<example_resource_name>"
  network_security_group_name = "<example_resource_name>"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Deny" # CRITICAL: Change access to Deny to remove the Allow condition
  protocol                    = "Udp"
  source_address_prefix       = "*"
  destination_address_prefix  = "*"
  source_port_range           = "*"
  destination_port_range      = "*"
}

NativeIaC

// Update the existing NSG rule to block UDP from the Internet
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-09-01' existing = {
  name: '<example_resource_name>'
}

resource rule 'Microsoft.Network/networkSecurityGroups/securityRules@2023-09-01' = {
  name: '${nsg.name}/<example_resource_name>'
  properties: {
    priority: 100
    direction: 'Inbound'
    access: 'Deny' // CRITICAL: Change access to Deny so UDP from Internet is not allowed
    protocol: 'Udp'
    sourceAddressPrefix: '*'
    destinationAddressPrefix: '*'
    sourcePortRange: '*'
    destinationPortRange: '*'
  }
}

Other

1In the Azure portal, go to Network security groups and open the NSG attached to the resource
2Select Inbound security rules
3Find any rule with Protocol = UDP, Direction = Inbound, Action = Allow, and Source set to Any/Internet/0.0.0.0/0
4Click the rule, set Action to Deny (or change Source to a specific trusted range), then Save
5Repeat for any remaining UDP Allow rules from the Internet

Check Code

from prowler.lib.check.models import Check, Check_Report_Azure
from prowler.providers.azure.services.network.network_client import network_client


class network_udp_internet_access_restricted(Check):
    def execute(self) -> Check_Report_Azure:
        findings = []
        for subscription, security_groups in network_client.security_groups.items():
            subscription_name = network_client.subscriptions.get(
                subscription, subscription
            )
            for security_group in security_groups:
                report = Check_Report_Azure(
                    metadata=self.metadata(), resource=security_group
                )
                report.subscription = subscription
                report.status = "PASS"
                report.status_extended = f"Security Group {security_group.name} from subscription {subscription_name} ({subscription}) has UDP internet access restricted."
                rule_fail_condition = any(
                    (
                        rule.protocol in ["UDP", "Udp"]
                        and (
                            rule.source_address_prefix
                            and rule.source_address_prefix
                            in ["Internet", "*", "0.0.0.0/0"]
                        )
                        and rule.access == "Allow"
                        and rule.direction == "Inbound"
                    )
                    for rule in security_group.security_rules
                )
                if rule_fail_condition:
                    report.status = "FAIL"
                    report.status_extended = f"Security Group {security_group.name} from subscription {subscription_name} ({subscription}) has UDP internet access allowed."
                findings.append(report)

        return findings