azure-sql-server-public-firewall
SQL logical server with publicNetworkAccess=Enabled and a 0.0.0.0–255.255.255.255 firewall rule is reachable from the public internet on port 1433.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?server) ==
RelationalDatabase
?server.provider_type == 'Microsoft.Sql/servers'
?server.properties.publicNetworkAccess != 'Disabled' # Enabled or null/absent (default=Enabled for older servers)
node_type(?firewallRule) == Firewall
?firewallRule.provider_type == 'Microsoft.Sql/servers/firewallRules'
?firewallRule.properties.startIpAddress == '0.0.0.0'
?firewallRule.properties.endIpAddress == '255.255.255.255' # true full-internet rule; endIp=0.0.0.0 is Azure-only tag — do NOT match
emit
| source type | RelationalDatabase |
|---|---|
| target type | AnonymousIdentity |
| source | ?server |
| target | <AnonymousIdentity> |
| conditions | network_reachability |
| state logic | ACTIVE: the server is reachable from any internet IPv4 host on port 1433. SQL auth is always available; Entra auth requires a valid Entra identity but the TCP endpoint itself is open. Note: the separate azure-sql-server-allow-azure-services rule handles the AllowAllWindowsAzureIps special case (startIp/endIp=0.0.0.0/0.0.0.0). The where clause guards publicNetworkAccess != 'Disabled' to prevent emission when the service-level flag overrides all firewall rules. |
Narrative
{server.name} has publicNetworkAccess=Enabled and a firewall rule allowing all IPv4 addresses (0.0.0.0–255.255.255.255), exposing SQL Server port 1433 to the public internet. Any internet host can attempt SQL authentication or Entra authentication against this server.
Raw rule rules/derived/azure/sql.yaml
id: azure-sql-server-public-firewall
emits: ExposedToInternet
description: "SQL logical server with publicNetworkAccess=Enabled and a 0.0.0.0\u2013255.255.255.255 firewall\
\ rule is reachable from the public internet on port 1433."
match:
- - server: null
- Contains
- firewallRule: null
where:
- node_type(?server) == RelationalDatabase
- ?server.provider_type == 'Microsoft.Sql/servers'
- '?server.properties.publicNetworkAccess != ''Disabled'' # Enabled or null/absent (default=Enabled for
older servers)'
- node_type(?firewallRule) == Firewall
- ?firewallRule.provider_type == 'Microsoft.Sql/servers/firewallRules'
- ?firewallRule.properties.startIpAddress == '0.0.0.0'
- "?firewallRule.properties.endIpAddress == '255.255.255.255' # true full-internet rule; endIp=0.0.0.0\
\ is Azure-only tag \u2014 do NOT match"
emit:
source_type: RelationalDatabase
target_type: AnonymousIdentity
source: ?server
target: <AnonymousIdentity>
permissions: []
conditions:
- network_reachability
state_logic: 'ACTIVE: the server is reachable from any internet IPv4 host on port 1433. SQL auth is
always available; Entra auth requires a valid Entra identity but the TCP endpoint itself is open.
Note: the separate azure-sql-server-allow-azure-services rule handles the AllowAllWindowsAzureIps
special case (startIp/endIp=0.0.0.0/0.0.0.0). The where clause guards publicNetworkAccess != ''Disabled''
to prevent emission when the service-level flag overrides all firewall rules.'
confidence: '0.95'
derived_from:
- "<Contains edge_id (server \u2192 firewallRule)>"
- <firewallRule.properties.startIpAddress/endIpAddress>
- <server.properties.publicNetworkAccess>
false_positive_note: "Two critical guards must both pass before emitting: (1) publicNetworkAccess must\
\ be 'Enabled' (or absent/null \u2014 old servers default\n to Enabled); if 'Disabled', the service-level\
\ flag wins and the firewall\n rule is irrelevant \u2014 skip entirely.\n(2) The firewall rule\
\ must cover the FULL public internet: startIpAddress=0.0.0.0\n AND endIpAddress=255.255.255.255.\
\ The special AllowAllWindowsAzureIps entry\n has startIpAddress=endIpAddress=0.0.0.0 (a single\
\ IP) and means \"allow Azure\n datacenter ranges\" \u2014 this is multi-tenant Azure risk, not\
\ public internet\n exposure; emit ExposedToTenant for that pattern instead.\nExposedToInternet\
\ here means any unauthenticated TCP SYN can reach port 1433. Actual data access also requires valid\
\ credentials (SQL login or Entra identity); the network exposure edge is correct regardless \u2014\
\ it represents the threat surface. Private-endpoint-only servers (publicNetworkAccess=Disabled) are\
\ NOT affected."
narrative: "{server.name} has publicNetworkAccess=Enabled and a firewall rule allowing all IPv4 addresses\
\ (0.0.0.0\u2013255.255.255.255), exposing SQL Server port 1433 to the public internet. Any internet\
\ host can attempt SQL authentication or Entra authentication against this server."