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.

derived azure emits ExposedToInternet

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 typeNoSQLDatabase
target typeAnonymousIdentity
source?account
targetazure:anonymous-identity
state logicif ?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.'
move · open · esc close