Skip to main content
KBY Technologies Logo
cd ../incident-runbooks
sys/runbooks/azure-network-security-group-default-allowvnetinbound-rule-combined-with-flat-vnet-peering-exposing-lateral-movement.md
Azure Network Segmentationhigh severity

Azure Network Security Group default ‘AllowVnetInBound’ rule combined with flat VNet peering exposing lateral movement

Severity
high
Reviewed
18 Jul 2026
Target time
~15 minutes

01 Incident diagnostics

The Symptom
Security review or a live incident shows a compromised VM in a low-trust spoke (e.g. a shared dev/test VNet) successfully completing TCP connections into production database or app-tier subnets on ports that were never explicitly allowlisted, despite each subnet having its own NSG attached.
Detection
Run az network watcher show-security-group-view --resource-group --vm and inspect effectiveSecurityRules for AllowVnetInBound with sourceAddressPrefix listing multiple peered CIDRs. Cross-check NSG Flow Logs via Traffic Analytics with a KQL filter on NSGFlowLog_CL | where NSGRule_s == "AllowVnetInBound" and FlowStatus_s == "A" to enumerate which peered VNet ranges are actually traversing the default allow.
Root Cause
The built-in AllowVnetInBound rule matches the VirtualNetwork service tag, which Azure dynamically expands to include the local VNet's address space plus every VNet address space reachable via active peerings, including AllowForwardedTraffic and UseRemoteGateways settings. In topologies using direct spoke-to-spoke mesh peering rather than hub-spoke with a forced-tunnel NVA, this tag silently aggregates every peered spoke's CIDR, so an NSG containing only default rules provides zero segmentation between tiers that were assumed to be isolated by separate VNets.
Prevention
Replace direct spoke-to-spoke mesh peering with hub-spoke topology forcing all inter-spoke traffic through Azure Firewall via UDR 0.0.0.0/0, and deploy Azure Virtual Network Manager security admin rules to enforce a global deny on VirtualNetwork-tagged inbound traffic that NSG owners cannot override. Alert on new AllowVnetInBound flow log entries crossing tier boundaries using a scheduled Log Analytics query against NSGFlowLog_CL, and gate new peering creation behind an Azure Policy that requires an explicit deny rule below priority 4096 on any NSG attached to a production subnet.
Blast Radius
  • Any subnet peered directly to a compromised VNet is reachable on all protocols and ports, not just the ports the application requires
  • Private endpoints and PaaS resources (SQL, Storage, Key Vault) exposed via service endpoints inherit the same VirtualNetwork-tag reachability
  • East-west traffic bypasses any centralised NVA or Azure Firewall inspection because peering routes traffic directly between spokes
  • Newly peered VNets automatically inherit exposure without any NSG change, since the tag recalculates on every peering addition
  • Incident scope expands from a single compromised host to every production tier within peering distance, defeating VNet-based segmentation assumptions
03

Apply the intervention

Before you execute

Confirm the incident scope, obtain approved privileged access, and capture the current configuration before applying changes.

Fix commands and configuration

# Enumerate effective rules on the affected NIC az network nic list-effective-nsg --resource-group rg-spoke-prod --name nic-app01 --query "value[].effectiveSecurityRules[?name=='AllowVnetInBound']" # Insert an explicit deny beneath the default rule priority band az network nsg rule create --resource-group rg-spoke-prod --nsg-name nsg-prod-web --name Deny-Lateral-VNet --priority 100 --direction Inbound --access Deny --protocol '*' --source-address-prefixes VirtualNetwork --destination-address-prefixes '*' --destination-port-ranges '*' # Re-permit only the specific required flows using Application Security Groups az network asg create --resource-group rg-spoke-prod --name asg-app-tier az network nsg rule create --resource-group rg-spoke-prod --nsg-name nsg-prod-web --name Allow-App-Tier-443 --priority 90 --direction Inbound --access Allow --protocol Tcp --source-asgs asg-app-tier --destination-port-ranges 443 # Stop forwarding traffic across peerings that don't require it az network vnet peering update --resource-group rg-hub --vnet-name vnet-hub --name peer-to-spoke-dev --set allowForwardedTraffic=false
04

Verify, roll back or escalate

Verify recovery

Repeat the detection checks after the intervention and confirm that the original symptom no longer occurs.

Rollback

Stop if impact increases. Restore the captured pre-change configuration or approved backup, then reassess before retrying.

Escalate when

Escalate to the platform owner or security incident lead when recovery is unavailable, scope is uncertain, or privileged access cannot be verified.

After recovery

Prevent recurrence and continue investigating

Related material stays below the operational procedure so it cannot distract from containment and recovery.