azure-disk-exposes-credential
A disk that can be SAS-exported and contains secrets exposes those credentials as accessible to external parties. The state (ACTIVE vs CONDITIONAL) depends on the CanExfiltrate edge state.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?disk) in [
BlockStorage, Snapshot]
emit
| source type | Storage |
|---|---|
| target type | Secret |
| source | ?disk |
| target | ?secret |
| permissions | Microsoft.Compute/disks/beginGetAccess/action (or snapshots/beginGetAccess/action) |
| state logic | ExposesCredential represents that the disk (Storage node) contains and can leak the credential material. The state inherits from the contributing CanExfiltrate edge: if CanExfiltrate(principal -> disk) is ACTIVE, then ExposesCredential is ACTIVE. If CanExfiltrate is CONDITIONAL(network_reachability), then ExposesCredential is CONDITIONAL(network_reachability). If the disk is CMK-encrypted and CanReadData is CONDITIONAL(key_permission), the credential plaintext is unreachable without decrypt (see credential-chains.yaml decrypt-gates-secret-read for the upgrade pattern). |
Narrative
Disk {source.name} contains and can expose credential material ({target.name}) to any principal with SAS export access (CanExfiltrate). See credential-chains.yaml for the CredentialsFor -> CanImpersonate chain.
Raw rule rules/derived/azure/disks.yaml
id: azure-disk-exposes-credential
emits: ExposesCredential
description: A disk that can be SAS-exported and contains secrets exposes those credentials as accessible
to external parties. The state (ACTIVE vs CONDITIONAL) depends on the CanExfiltrate edge state.
match:
- - disk: null
- ContainsSecret
- secret: null
- - principal: null
- CanExfiltrate
- disk: null
where:
- node_type(?disk) in [BlockStorage, Snapshot]
emit:
source_type: Storage
target_type: Secret
source: ?disk
target: ?secret
permissions:
- Microsoft.Compute/disks/beginGetAccess/action (or snapshots/beginGetAccess/action)
state_logic: 'ExposesCredential represents that the disk (Storage node) contains and can leak the credential
material. The state inherits from the contributing CanExfiltrate edge: if CanExfiltrate(principal
-> disk) is ACTIVE, then ExposesCredential is ACTIVE. If CanExfiltrate is CONDITIONAL(network_reachability),
then ExposesCredential is CONDITIONAL(network_reachability). If the disk is CMK-encrypted and CanReadData
is CONDITIONAL(key_permission), the credential plaintext is unreachable without decrypt (see credential-chains.yaml
decrypt-gates-secret-read for the upgrade pattern).'
confidence: min(contributing_confidences)
derived_from:
- <ContainsSecret edge_id>
- <CanExfiltrate edge_id>
false_positive_note: 'ExposesCredential on a disk is a structural fact (disk contains & can leak cred).
Actual credential access requires CanExfiltrate(principal -> disk) present in the path. Do not over-claim:
ExposesCredential stops at the credential artifact; actual impersonation requires an additional CredentialsFor
explicit link (credentials-chains.yaml read-secret-yields-identity).'
narrative: Disk {source.name} contains and can expose credential material ({target.name}) to any principal
with SAS export access (CanExfiltrate). See credential-chains.yaml for the CredentialsFor -> CanImpersonate
chain.