azure-postgres-mysql-admin-reset-readdata

Admin password reset capability (CanModifyConfiguration to server config) plus network reachability to the DB endpoint yields full data-plane read of all databases.

derived azure emits CanReadData

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanModifyConfiguration {'server': None}

where

node_class(?server) == Data and node_type(?server) == RelationalDatabase node_type(?server) matched provider_type in ['Microsoft.DBforPostgreSQL/flexibleServers', 'Microsoft.DBforMySQL/flexibleServers'] edge produced by azure-postgres-mysql-admin-password-reset (CanModifyConfiguration from flexibleServers/write on this server)

emit

source typeIdentity
target typeRelationalDatabase
source?principal
target?server
permissionsMicrosoft.DBforPostgreSQL/flexibleServers/write Microsoft.DBforMySQL/flexibleServers/write
conditionsnetwork_reachability
state logicif ?server.properties.publicNetworkAccess == 'Disabled' (private-access topology / VNet injection): CONDITIONAL(network_reachability) — no public endpoint exists; attacker must have a foothold in the delegated subnet or a peered VNet to reach port 5432/3306; elif ?server.properties.publicNetworkAccess == 'Enabled' AND a firewall rule admitting the attacker's source IP exists (or rule 0.0.0.0–255.255.255.255): ACTIVE; elif ?server.properties.publicNetworkAccess == 'Enabled' AND no firewall rule covers the attacker's source: CONDITIONAL(network_reachability); if a deny assignment or deny Azure Policy covers flexibleServers/write at effective scope (blocking the upstream CanModifyConfiguration): BLOCKED.

Narrative

{principal.name} can modify {server.name} configuration (via flexibleServers/write), allowing the native administrator password to be reset to an attacker-chosen value. Combined with network reachability to the database endpoint, the attacker can authenticate as the admin user and read all databases and tables. Application data frequently contains embedded credentials, connection strings, and API keys (see credential-chains.yaml for the ContainsSecret -> CredentialsFor -> CanImpersonate roll-up).

Raw rule rules/derived/azure/postgres-mysql.yaml

id: azure-postgres-mysql-admin-reset-readdata
emits: CanReadData
description: Admin password reset capability (CanModifyConfiguration to server config) plus network reachability
  to the DB endpoint yields full data-plane read of all databases.
match:
- - principal: null
  - CanModifyConfiguration
  - server: null
where:
- node_class(?server) == Data and node_type(?server) == RelationalDatabase
- node_type(?server) matched provider_type in ['Microsoft.DBforPostgreSQL/flexibleServers', 'Microsoft.DBforMySQL/flexibleServers']
- edge produced by azure-postgres-mysql-admin-password-reset (CanModifyConfiguration from flexibleServers/write
  on this server)
emit:
  source_type: Identity
  target_type: RelationalDatabase
  source: ?principal
  target: ?server
  permissions:
  - Microsoft.DBforPostgreSQL/flexibleServers/write
  - Microsoft.DBforMySQL/flexibleServers/write
  conditions:
  - network_reachability
  state_logic: "if ?server.properties.publicNetworkAccess == 'Disabled' (private-access topology / VNet\
    \ injection): CONDITIONAL(network_reachability) \u2014 no public endpoint exists; attacker must have\
    \ a foothold in the delegated subnet or a peered VNet to reach port 5432/3306; elif ?server.properties.publicNetworkAccess\
    \ == 'Enabled' AND a firewall rule admitting the attacker's source IP exists (or rule 0.0.0.0\u2013\
    255.255.255.255): ACTIVE; elif ?server.properties.publicNetworkAccess == 'Enabled' AND no firewall\
    \ rule covers the attacker's source: CONDITIONAL(network_reachability); if a deny assignment or deny\
    \ Azure Policy covers flexibleServers/write at effective scope (blocking the upstream CanModifyConfiguration):\
    \ BLOCKED."
  confidence: '0.90'
  derived_from:
  - 'CanModifyConfiguration edge: source=?principal, target=?server, rule=azure-postgres-mysql-admin-password-reset'
  false_positive_note: "Network reachability is a HARD gate. A private-access server (VNet-injected, publicNetworkAccess\
    \ == Disabled) has no public endpoint \u2014 do NOT emit ACTIVE for CanReadData unless the principal\
    \ is provably inside the VNet or a peered network. For public-access servers: only ACTIVE when a firewall\
    \ rule admits the attacker's source IP; the rule range 0.0.0.0\u2013255.255.255.255 means any internet\
    \ host, which yields ACTIVE. The \"Allow Azure services\" shorthand (startIpAddress = 0.0.0.0, endIpAddress\
    \ = 0.0.0.0) admits only Azure backbone IPs, NOT arbitrary internet hosts \u2014 do not treat it as\
    \ fully open. This is a two-step derived edge (ARM write -> DB read); its state is capped by the weaker\
    \ of CanModifyConfiguration and network_reachability (per edge_state_model weakest-contributor rule).\
    \ Application databases frequently contain embedded connection strings and secrets \u2014 see credential-chains.yaml\
    \ for ContainsSecret -> CredentialsFor -> CanImpersonate roll-up when the DB ContainsSecret."
  narrative: '{principal.name} can modify {server.name} configuration (via flexibleServers/write), allowing
    the native administrator password to be reset to an attacker-chosen value. Combined with network reachability
    to the database endpoint, the attacker can authenticate as the admin user and read all databases and
    tables. Application data frequently contains embedded credentials, connection strings, and API keys
    (see credential-chains.yaml for the ContainsSecret -> CredentialsFor -> CanImpersonate roll-up).'
move · open · esc close