Back to Checks
azure

Network security group restricts inbound HTTP (port 80) access from the Internet

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

Azure NSG are evaluated for inbound rules that allow public HTTP access on TCP 80, including cases where 80 is covered by a port range, from 0.0.0.0/0, Internet, or *.

Risk

Exposing TCP 80 to the Internet increases attack surface:

  • Web recon and exploits compromise integrity and availability
  • Cleartext HTTP can leak credentials, cookies, and data, harming confidentiality
  • Public endpoints enable bot abuse and footholds for lateral movement

Run this check with Prowler

Run in Prowler Cloud
Run
prowler azure --checks network_http_internet_access_restricted

Recommendation

Apply least privilege at NSGs:

  • Remove broad allows to TCP 80, or restrict to trusted sources
  • Enforce HTTPS (443) and redirect or block HTTP
  • Use private access patterns and segmentation for defense in depth
  • If exposure is necessary, place services behind a WAF, enable DDoS protections, and monitor

Remediation

CLI

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

Terraform

# Deny inbound HTTP from Internet on an existing NSG
resource "azurerm_network_security_rule" "deny_http_internet" {
  name                        = "deny-http-internet"
  resource_group_name         = "<example_resource_name>"
  network_security_group_name = "<example_resource_name>"
  priority                    = 100
  direction                   = "Inbound"
  access                      = "Deny"           # CRITICAL: Deny so HTTP from Internet is not allowed
  protocol                    = "Tcp"
  source_address_prefix       = "Internet"       # CRITICAL: Matches traffic from the Internet
  destination_address_prefix  = "*"
  source_port_range           = "*"
  destination_port_range      = "80"             # CRITICAL: Blocks port 80 (HTTP)
}

NativeIaC

// Deny inbound HTTP from Internet on an existing NSG
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-09-01' existing = {
  name: '<example_resource_name>'
}

resource denyHttp 'Microsoft.Network/networkSecurityGroups/securityRules@2023-09-01' = {
  name: '${nsg.name}/Deny-HTTP-Internet'
  properties: {
    priority: 100
    direction: 'Inbound'
    access: 'Deny'                 // CRITICAL: Denies the HTTP rule so it no longer allows Internet traffic
    protocol: 'Tcp'
    sourceAddressPrefix: 'Internet' // CRITICAL: Targets traffic coming from the Internet
    destinationAddressPrefix: '*'
    sourcePortRange: '*'
    destinationPortRange: '80'      // CRITICAL: Blocks port 80 (HTTP)
  }
}

Other

1In Azure Portal, go to Network Security Groups and select your NSG
2Open Inbound security rules
3Find any rule with Action Allow, Protocol TCP or Any, Destination port 80 (or range including 80), and Source Internet/*/0.0.0.0/0
4Select the rule and click Edit
5Change Action to Deny (or delete the rule)
6Click Save

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_http_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 HTTP internet access restricted."
                rule_fail_condition = any(
                    (
                        rule.destination_port_range == "80"
                        or (
                            (
                                rule.destination_port_range
                                and "-" in rule.destination_port_range
                            )
                            and int(rule.destination_port_range.split("-")[0]) <= 80
                            and int(rule.destination_port_range.split("-")[1]) >= 80
                        )
                    )
                    and rule.protocol in ["TCP", "Tcp", "*"]
                    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 HTTP internet access allowed."
                findings.append(report)

        return findings