azure-vwan-vpn-psk-read
A principal with read access to a hub VPN connection resource can retrieve the pre-shared key (PSK) in plaintext from the ARM GET response (sharedKey field). The PSK enables establishing a rogue S2S VPN tunnel to the same hub, granting network-layer transit reach to all connected spoke VNets.
match (effective permission)
{
"action": "Microsoft.Network/vpnGateways/vpnConnections/read",
"scope_type": "resource|resourceGroup|subscription"
}
where
vpnConnections resource properties.sharedKey is non-null and non-empty
emit
| source type | Identity |
|---|---|
| target type | Secret |
| source | <principal> |
| target | <PSK secret modeled as a Secret node for the VPN connection> |
| permissions | Microsoft.Network/vpnGateways/vpnConnections/read |
| state logic | ACTIVE when the principal has effective vpnConnections/read permission at the gateway or containing scope AND the sharedKey field is non-null in the ARM resource. The PSK is stored and readable regardless of whether the tunnel is currently connected (a NotConnected or Connecting tunnel still exposes the PSK, enabling an attacker to establish a new tunnel). CONDITIONAL(iam_permission) if the permission is inherited from a broad scope (e.g. subscription-level Reader) and a deny assignment at a narrower scope may override it — verify effective permissions, not just assignment role. |
Narrative
{principal.name} can read the pre-shared key of VPN connection {vpnConnection.name} on hub gateway {vpnGateway.name} (vpnGateways/vpnConnections/read). The PSK enables establishing a rogue S2S tunnel to the same hub, granting network transit reach to all spoke VNets and branches connected to hub {hub.name}.
Raw rule rules/derived/azure/vwan.yaml
id: azure-vwan-vpn-psk-read
emits: CanReadSecret
description: A principal with read access to a hub VPN connection resource can retrieve the pre-shared
key (PSK) in plaintext from the ARM GET response (sharedKey field). The PSK enables establishing a rogue
S2S VPN tunnel to the same hub, granting network-layer transit reach to all connected spoke VNets.
match_effective_permission:
action: Microsoft.Network/vpnGateways/vpnConnections/read
scope_type: resource|resourceGroup|subscription
where:
- vpnConnections resource properties.sharedKey is non-null and non-empty
emit:
source_type: Identity
target_type: Secret
source: <principal>
target: <PSK secret modeled as a Secret node for the VPN connection>
permissions:
- Microsoft.Network/vpnGateways/vpnConnections/read
state_logic: "ACTIVE when the principal has effective vpnConnections/read permission at the gateway\
\ or containing scope AND the sharedKey field is non-null in the ARM resource. The PSK is stored and\
\ readable regardless of whether the tunnel is currently connected (a NotConnected or Connecting tunnel\
\ still exposes the PSK, enabling an attacker to establish a new tunnel). CONDITIONAL(iam_permission)\
\ if the permission is inherited from a broad scope (e.g. subscription-level Reader) and a deny assignment\
\ at a narrower scope may override it \u2014 verify effective permissions, not just assignment role."
derived_from:
- '<effective permission record: vpnGateways/vpnConnections/read>'
- <vpnConnection ARM resource with sharedKey field>
false_positive_note: "P2S VPN gateways use certificate or Azure AD / Entra OIDC authentication \u2014\
\ no PSK is stored; do NOT emit for P2sVpnGateways. ExpressRoute circuits also have no PSK. Only emit\
\ for Microsoft.Network/vpnGateways/vpnConnections where sharedKey is present. Reader role at subscription\
\ scope includes vpnConnections/read and CAN read the PSK \u2014 the PSK is not separately gated beyond\
\ ARM read access. Note that retrieving the PSK alone does not yield immediate network access: the\
\ attacker must also provision a compatible VPN device/gateway configured with the same parameters\
\ (IKEv2 settings, BGP ASN if used) to establish the tunnel \u2014 model as ACTIVE because the prerequisite\
\ (PSK material) is fully obtained. Do not emit if sharedKey is null or empty (AAD/certificate-authenticated\
\ connections)."
narrative: '{principal.name} can read the pre-shared key of VPN connection {vpnConnection.name} on hub
gateway {vpnGateway.name} (vpnGateways/vpnConnections/read). The PSK enables establishing a rogue
S2S tunnel to the same hub, granting network transit reach to all spoke VNets and branches connected
to hub {hub.name}.'