azure-netapp-volume-write-export-policy

volumes/write permission on ANF volume enables export policy mutation.

derived azure emits CanModifyConfiguration

match

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

{'principal': None} HasPermission {'volume': None}

where

node_class(?volume) == Storage and node_type(?volume) == FileStorage ?volume.provider_type == 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes' ?principal has EFFECTIVE Microsoft.NetApp/netAppAccounts/capacityPools/volumes/write at ?volume scope (Owner, Contributor, or custom role with volumes/write) ?volume.properties.provisioningState == 'Succeeded' # volume is online

emit

source typeIdentity
target typeFileStorage
source?principal
target?volume
permissionsMicrosoft.NetApp/netAppAccounts/capacityPools/volumes/write
conditionsiam_permission
state logicif a deny assignment covers volumes/write at effective scope: BLOCKED; elif ?volume.properties.provisioningState != 'Succeeded': CONDITIONAL(service_state); else ACTIVE. volumes/write is a control-plane action that allows export policy mutation (opening NFS export to arbitrary IP ranges or widening SMB ACL scope). This configuration change can enable data-plane access but does NOT itself constitute data-plane write access. Data-plane CanWriteData is gated on network_reachability to the delegated subnet.

Narrative

{principal.name} has ARM write permission on ANF volume {volume.name} (Microsoft.NetApp/netAppAccounts/capacityPools/volumes/write) and can mutate the export policy to include their own IP or open it to 0.0.0.0/0. Actual data-plane write access requires network reachability to the delegated subnet.

Raw rule rules/derived/azure/netapp.yaml

id: azure-netapp-volume-write-export-policy
emits: CanModifyConfiguration
description: volumes/write permission on ANF volume enables export policy mutation.
match:
- - principal: null
  - HasPermission
  - volume: null
where:
- node_class(?volume) == Storage and node_type(?volume) == FileStorage
- ?volume.provider_type == 'Microsoft.NetApp/netAppAccounts/capacityPools/volumes'
- ?principal has EFFECTIVE Microsoft.NetApp/netAppAccounts/capacityPools/volumes/write at ?volume scope
  (Owner, Contributor, or custom role with volumes/write)
- '?volume.properties.provisioningState == ''Succeeded''  # volume is online'
emit:
  source_type: Identity
  target_type: FileStorage
  source: ?principal
  target: ?volume
  permissions:
  - Microsoft.NetApp/netAppAccounts/capacityPools/volumes/write
  conditions:
  - iam_permission
  state_logic: 'if a deny assignment covers volumes/write at effective scope: BLOCKED; elif ?volume.properties.provisioningState
    != ''Succeeded'': CONDITIONAL(service_state); else ACTIVE. volumes/write is a control-plane action
    that allows export policy mutation (opening NFS export to arbitrary IP ranges or widening SMB ACL
    scope). This configuration change can enable data-plane access but does NOT itself constitute data-plane
    write access. Data-plane CanWriteData is gated on network_reachability to the delegated subnet.'
  confidence: '0.90'
  derived_from:
  - ?principal HasPermission ?volume
  false_positive_note: volumes/write grants control-plane mutation of export policy rules (IP ranges,
    access levels, Kerberos enforcement) and NFS re-export, or SMB ACL settings. This is a configuration
    capability, NOT data-plane access. After mutating the export policy, the attacker still requires network
    reachability to the delegated subnet to mount the volume and write data. CanModifyConfiguration correctly
    models the control-plane mutation; downstream data-plane CanWriteData should be CONDITIONAL(network_reachability).
    A deny assignment on volumes/write DOES block this capability.
  narrative: '{principal.name} has ARM write permission on ANF volume {volume.name} (Microsoft.NetApp/netAppAccounts/capacityPools/volumes/write)
    and can mutate the export policy to include their own IP or open it to 0.0.0.0/0. Actual data-plane
    write access requires network reachability to the delegated subnet.'
move · open · esc close