azure-cosmosdb-public-endpoint
Cosmos DB account with no IP firewall and public network access enabled exposes its data-plane endpoint to the internet - any caller with a valid token can reach it.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
[{'account': None}]
where
node_class(?account) == Data and node_type(?account) ==
NoSQLDatabase
node_type(?account) matched provider_type == 'Microsoft.DocumentDB/databaseAccounts'
?account.properties.publicNetworkAccess != 'Disabled'
?account.properties.ipRules is empty or null
?account.properties.virtualNetworkRules is empty or null
emit
| source type | NoSQLDatabase |
|---|---|
| target type | AnonymousIdentity |
| source | ?account |
| target | azure:anonymous-identity |
| state logic | if ?account.properties.publicNetworkAccess == 'Disabled': DO NOT EMIT (public endpoint is blocked; private endpoints are the only data path); elif ?account.properties.ipRules is non-empty: DO NOT EMIT (firewall restricts to listed IPs — not open to all internet); elif ?account.properties.virtualNetworkRules is non-empty AND ?account.properties.ipRules is empty: CONDITIONAL(network_reachability) — VNet rules restrict access to specific subnets; internet callers blocked; elif ?account.properties.ipRules contains ONLY '0.0.0.0' (Azure datacenter IPs): DO NOT EMIT ExposedToInternet — emit ExposedToTenant (all Azure-hosted principals can reach it, but arbitrary internet IPs cannot); else ACTIVE (no firewall, public network accessible). |
Narrative
{account.name} has no IP firewall and public network access is enabled. The Cosmos DB data-plane endpoint is reachable from the public internet. Any attacker who obtains a valid master key (via listKeys) or a data-plane Entra token can reach the database without any network-layer barrier.
Raw rule rules/derived/azure/cosmosdb.yaml
id: azure-cosmosdb-public-endpoint
emits: ExposedToInternet
description: "Cosmos DB account with no IP firewall and public network access enabled exposes its data-plane\
\ endpoint to the internet \u2014 any caller with a valid token can reach it."
match:
- - account: null
where:
- node_class(?account) == Data and node_type(?account) == NoSQLDatabase
- node_type(?account) matched provider_type == 'Microsoft.DocumentDB/databaseAccounts'
- ?account.properties.publicNetworkAccess != 'Disabled'
- ?account.properties.ipRules is empty or null
- ?account.properties.virtualNetworkRules is empty or null
emit:
source_type: NoSQLDatabase
target_type: AnonymousIdentity
source: ?account
target: azure:anonymous-identity
permissions: []
conditions: []
state_logic: "if ?account.properties.publicNetworkAccess == 'Disabled': DO NOT EMIT (public endpoint\
\ is blocked; private endpoints are the only data path); elif ?account.properties.ipRules is non-empty:\
\ DO NOT EMIT (firewall restricts to listed IPs \u2014 not open to all internet); elif ?account.properties.virtualNetworkRules\
\ is non-empty AND ?account.properties.ipRules is empty: CONDITIONAL(network_reachability) \u2014\
\ VNet rules restrict access to specific subnets; internet callers blocked; elif ?account.properties.ipRules\
\ contains ONLY '0.0.0.0' (Azure datacenter IPs): DO NOT EMIT ExposedToInternet \u2014 emit ExposedToTenant\
\ (all Azure-hosted principals can reach it, but arbitrary internet IPs cannot); else ACTIVE (no firewall,\
\ public network accessible)."
confidence: '0.92'
derived_from:
- <publicNetworkAccess property record>
- <ipRules property record>
false_positive_note: "ExposedToInternet does NOT mean unauthenticated access \u2014 a valid authorization\
\ token (master key or Entra + sqlRoleAssignment) is always required by Cosmos DB. This edge means\
\ the NETWORK is not a barrier; an attacker with any valid credential can reach the endpoint from\
\ the public internet. Firewall with non-empty ipRules restricts access \u2014 do not emit when ipRules\
\ is non-empty (even if the rules seem broad). The '0.0.0.0' sentinel allows Azure datacenter IPs\
\ only \u2014 emit ExposedToTenant rather than ExposedToInternet for that case (it's a broad but Azure-bounded\
\ blast radius). publicNetworkAccess=Disabled is a hard block \u2014 never emit ExposedToInternet\
\ when that property is set. This only covers the data-plane endpoint; the ARM listKeys plane is always\
\ internet-accessible for callers with ARM RBAC permissions (handled by note in listkeys rule, not\
\ a separate ExposedToInternet \u2014 ARM is always public)."
narrative: '{account.name} has no IP firewall and public network access is enabled. The Cosmos DB data-plane
endpoint is reachable from the public internet. Any attacker who obtains a valid master key (via listKeys)
or a data-plane Entra token can reach the database without any network-layer barrier.'