azure-nsg-inbound-open

An NSG effective inbound rule allows source=Internet (or 0.0.0.0/0) with action=Allow on a specific port - the firewall is open to the public internet for that port. CONDITIONAL(network_reachability): a public IP must also be present on an attached resource for the port to be externally reachable.

derived azure emits CanReachPort

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'nsg': None} LocatedIn {'subnetOrNic': None} {'resource': None} LocatedIn {'subnetOrNic': None}

where

node_type(?nsg) == Firewall # Microsoft.Network/networkSecurityGroups node_type(?resource) == Compute # VM, App Service, Container, etc. ?nsg has an effective inbound security rule where: properties.access == Allow AND properties.direction == Inbound AND properties.sourceAddressPrefix in {Internet, *, 0.0.0.0/0, ::/0} AND rule priority < effective deny rule priority for the same port/proto ?subnetOrNic is of type Subnet or NetworkInterface (LocatedIn target)

emit

source typeNetwork
target typeCompute
source?nsg
target?resource
conditionsnetwork_reachability
state logicCONDITIONAL(network_reachability): the NSG rule is open but the resource must also have a public IP or be fronted by an internet-facing load balancer for the port to be externally reachable. Set ACTIVE only when collector confirms a public IP is associated with the NIC or the subnet's resources.

Narrative

NSG {nsg.name} has an effective inbound Allow rule permitting traffic from the public internet (source=Internet/0.0.0.0/0) on port {port}. {resource.name} located in the NSG's associated subnet/NIC is reachable from the internet on that port if a public IP is also present.

Raw rule rules/derived/azure/nsg.yaml

id: azure-nsg-inbound-open
emits: CanReachPort
description: "An NSG effective inbound rule allows source=Internet (or 0.0.0.0/0) with action=Allow on\
  \ a specific port \u2014 the firewall is open to the public internet for that port. CONDITIONAL(network_reachability):\
  \ a public IP must also be present on an attached resource for the port to be externally reachable."
applies_to:
- azure
match:
- - nsg: null
  - LocatedIn
  - subnetOrNic: null
- - resource: null
  - LocatedIn
  - subnetOrNic: null
where:
- 'node_type(?nsg) == Firewall  # Microsoft.Network/networkSecurityGroups'
- 'node_type(?resource) == Compute  # VM, App Service, Container, etc.'
- '?nsg has an effective inbound security rule where: properties.access == Allow AND properties.direction
  == Inbound AND properties.sourceAddressPrefix in {Internet, *, 0.0.0.0/0, ::/0} AND rule priority <
  effective deny rule priority for the same port/proto'
- ?subnetOrNic is of type Subnet or NetworkInterface (LocatedIn target)
emit:
  source_type: Network
  target_type: Compute
  source: ?nsg
  target: ?resource
  permissions: []
  conditions:
  - network_reachability
  state_logic: 'CONDITIONAL(network_reachability): the NSG rule is open but the resource must also have
    a public IP or be fronted by an internet-facing load balancer for the port to be externally reachable.
    Set ACTIVE only when collector confirms a public IP is associated with the NIC or the subnet''s resources.'
  confidence: 0.85
  derived_from:
  - '<NSG effective inbound rule: source=Internet/0.0.0.0/0, action=Allow, port={port}>'
  - "<LocatedIn edge: NSG \u2192 Subnet/NIC>"
  - "<LocatedIn edge: Compute \u2192 Subnet/NIC>"
  false_positive_note: "CRITICAL: evaluate EFFECTIVE rules only (use effectiveNetworkSecurityGroups/action\
    \ on the NIC), not raw rule lists. A higher-priority Deny rule for the same port blocks the Allow.\
    \ For NICs with both a subnet NSG and a NIC NSG, the traffic must be allowed by the subnet NSG first\
    \ (inbound direction) and then by the NIC NSG; an Allow in one but a Deny in the other means the port\
    \ is NOT effectively open. Do NOT emit if:\n  - A higher-priority deny rule exists for the same port/source\
    \ combination.\n  - The resource has no public IP and is not fronted by an internet-facing LB\n  \
    \  (in that case the rule is a VNet-internal allow, not internet exposure).\n  - Only the default\
    \ rules (priorities 65000/65001/65500) are present \u2014 the\n    default DenyAllInBound at 65500\
    \ blocks all internet traffic.\nThe `Internet` service tag excludes VNet private ranges; `0.0.0.0/0`\
    \ covers all IPv4 but Azure does not route arbitrary internet traffic to private IPs. Treat both as\
    \ equivalent internet-source for exposure analysis. Note: source CIDRs covering all public IPv4 via\
    \ multiple rules (e.g., split /1 ranges) should also trigger this rule; document coverage via CIDR\
    \ composition at collector/evaluation time."
  narrative: NSG {nsg.name} has an effective inbound Allow rule permitting traffic from the public internet
    (source=Internet/0.0.0.0/0) on port {port}. {resource.name} located in the NSG's associated subnet/NIC
    is reachable from the internet on that port if a public IP is also present.
move · open · esc close