azure-rediscache-public-no-firewall
Cache for Redis with publicNetworkAccess=Enabled and no IP firewall rules exposes the Redis data-plane port 6380 (SSL) to the public internet.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
[{'cache': None}]
where
node_type(?cache) ==
Cache
?cache.provider_type == 'Microsoft.Cache/redis'
?cache.properties.publicNetworkAccess != 'Disabled' # absent/null defaults to Enabled for instances without explicit private-endpoint-only config
count(firewallRules for ?cache) == 0 # no IP firewall rules whatsoever
emit
| source type | Cache |
|---|---|
| target type | AnonymousIdentity |
| source | ?cache |
| target | <AnonymousIdentity> |
| conditions | network_reachability |
| state logic | if ?cache.properties.publicNetworkAccess == 'Disabled': DO NOT EMIT; elif ?cache is VNet-injected Premium (subnetId is set, publicNetworkAccess is absent or Disabled): DO NOT EMIT; elif firewallRules count == 0 AND publicNetworkAccess is Enabled (or absent/null): ACTIVE — the Redis endpoint port 6380 (SSL) is reachable from any internet IPv4 host. Authentication (key or requirepass) is still required unless authnotrequired=yes, but the network attack surface is fully public. Unauthenticated TCP connections can probe the endpoint regardless. Note: port 6379 (non-SSL) is disabled by default (enableNonSslPort=false); if enableNonSslPort=true, the non-SSL port is also exposed — no separate rule needed (same ExposedToInternet applies, lower confidentiality on the transport). |
Narrative
{cache.name} has publicNetworkAccess=Enabled (or defaults to it) with no IP firewall rules. The Redis data-plane port 6380 (SSL) is reachable from any internet host. Any caller with the Redis access key can connect directly; without additional network controls, brute-force and credential-spray attacks against the Redis password are feasible.
Raw rule rules/derived/azure/rediscache.yaml
id: azure-rediscache-public-no-firewall
emits: ExposedToInternet
description: Cache for Redis with publicNetworkAccess=Enabled and no IP firewall rules exposes the Redis
data-plane port 6380 (SSL) to the public internet.
match:
- - cache: null
where:
- node_type(?cache) == Cache
- ?cache.provider_type == 'Microsoft.Cache/redis'
- '?cache.properties.publicNetworkAccess != ''Disabled'' # absent/null defaults to Enabled for instances
without explicit private-endpoint-only config'
- 'count(firewallRules for ?cache) == 0 # no IP firewall rules whatsoever'
emit:
source_type: Cache
target_type: AnonymousIdentity
source: ?cache
target: <AnonymousIdentity>
permissions: []
conditions:
- network_reachability
state_logic: "if ?cache.properties.publicNetworkAccess == 'Disabled': DO NOT EMIT; elif ?cache is VNet-injected\
\ Premium (subnetId is set, publicNetworkAccess is absent or Disabled): DO NOT EMIT; elif firewallRules\
\ count == 0 AND publicNetworkAccess is Enabled (or absent/null): ACTIVE \u2014 the Redis endpoint\
\ port 6380 (SSL) is reachable from any internet IPv4 host. Authentication (key or requirepass) is\
\ still required unless authnotrequired=yes, but the network attack surface is fully public. Unauthenticated\
\ TCP connections can probe the endpoint regardless. Note: port 6379 (non-SSL) is disabled by default\
\ (enableNonSslPort=false); if enableNonSslPort=true, the non-SSL port is also exposed \u2014 no separate\
\ rule needed (same ExposedToInternet applies, lower confidentiality on the transport)."
confidence: '0.93'
derived_from:
- <cache.properties.publicNetworkAccess property>
- <firewallRules absence>
false_positive_note: "The absence of firewallRules does NOT mean anonymous access \u2014 Redis still\
\ requires the access key (requirepass) unless authnotrequired=yes. This edge models network-layer\
\ exposure (the TCP endpoint is publicly reachable), not data-layer access (which also requires the\
\ key). The combination of this edge and azure-rediscache-listkeys-exposes-credential in a path means\
\ an attacker can reach the endpoint AND has the key \u2192 full data access. VNet-injected Premium\
\ instances: when subnetId is set, Azure forces publicNetworkAccess=Disabled \u2014 do NOT emit regardless\
\ of other properties. If publicNetworkAccess is absent/null and subnetId is also absent, treat as\
\ Enabled (Standard and Basic tier default before the property was added)."
narrative: '{cache.name} has publicNetworkAccess=Enabled (or defaults to it) with no IP firewall rules.
The Redis data-plane port 6380 (SSL) is reachable from any internet host. Any caller with the Redis
access key can connect directly; without additional network controls, brute-force and credential-spray
attacks against the Redis password are feasible.'