What it is
A Network Security Group with an inbound Allow rule from the whole internet (*, 0.0.0.0/0, or the Internet service tag) on an admin or database port: RDP (3389), SSH (22), a database engine (SQL Server 1433, MySQL 3306, PostgreSQL 5432, Redis 6379, MongoDB 27017, Elasticsearch 9200, and friends), or a management protocol like WinRM or SMB. These are the ports internet-wide scanners probe continuously, and the protocols behind them authenticate with passwords or nothing at all: no Entra ID, no MFA, no conditional access. This is the specific, critical tier of the broader any-source NSG problem (AZF-0006 covers the generic pattern).
Why it happens
The paths into this state are all mundane. The portal's VM-create flow offers "Allow selected ports" for RDP and SSH, and taking it opens the port from any source, with only a small warning. A vendor needs database access "for the migration weekend", so 1433 gets opened and the weekend never ends. Someone can't get a connection working, widens the rule to * to rule out networking, and it works, so it ships.
The exposure also hides well. A rule doesn't have to say 3389 to open RDP: a port range like 1400-1500 quietly covers SQL Server's 1433, a comma list buries the sensitive port in the middle, and a * destination covers everything. Subnet-level NSGs make it worse by inheritance, since a permissive rule applies to every VM dropped into that subnet later. Eyeballing rule lists doesn't catch this; the port arithmetic has to actually be evaluated.
What it costs / blast radius
This is a blast radius, not a bill. A newly exposed RDP or SSH port starts receiving automated login attempts within minutes of appearing, because scanning the entire IPv4 space for these ports is cheap and continuous. From there the attacks are brute force and credential stuffing against protocols with no MFA, plus known CVEs (RDP has had wormable, pre-auth remote-code-execution vulnerabilities). Database ports are worse: Redis and Memcached historically ship with no authentication at all, and internet-exposed MongoDB instances have been mass-wiped for ransom repeatedly. (Azure behavior and public attack history; authored assessment.) The blast radius is the machine, its data, and everything reachable from it on a flat network.
See it
resource nsg 'Microsoft.Network/networkSecurityGroups@2023-09-01' = {
name: 'nsg-app'
location: location
properties: {
securityRules: [
{
name: 'allow-rdp' // "temporary", two years ago
properties: {
priority: 100
direction: 'Inbound'
access: 'Allow'
protocol: 'Tcp'
sourceAddressPrefix: '*' // the entire internet
sourcePortRange: '*'
destinationAddressPrefix: '*'
destinationPortRange: '3389' // RDP
}
}
{
name: 'allow-vendor-range'
properties: {
priority: 110
direction: 'Inbound'
access: 'Allow'
protocol: 'Tcp'
sourceAddressPrefix: 'Internet' // same exposure, different spelling
sourcePortRange: '*'
destinationAddressPrefix: '*'
destinationPortRange: '1400-1500' // quietly covers SQL Server (1433)
}
}
]
}
}// 1) Remove every inbound Allow from the internet on admin/DB ports.
// Don't scope it to an office IP "for now" (see AZF-0094) — take the
// port off the internet entirely.
// 2) RDP/SSH goes through Azure Bastion: TLS, Entra ID sign-in, audit
// trail, and zero public ports on the VMs themselves.
resource bastion 'Microsoft.Network/bastionHosts@2023-09-01' = {
name: 'bas-prod'
location: location
sku: { name: 'Standard' }
properties: {
ipConfigurations: [
{
name: 'ipconfig'
properties: {
subnet: { id: bastionSubnet.id } // the AzureBastionSubnet
publicIPAddress: { id: bastionPip.id }
}
}
]
}
}
// 3) Databases are never internet-facing: private endpoints inside the
// VNet, or at minimum the service firewall with public access off.How StratoLens helps
StratoLens evaluates every NSG rule across every subscription, does the port arithmetic (ranges, comma lists, and * included), and flags internet-facing admin and database ports as critical findings inside your own tenant. Its change history shows the day the "temporary" rule appeared, so exposure gets caught as a finding, not as an incident.