gcp-memorystore-auth-string-grants-data-read
Possession of the Redis AUTH string (retrieved via redis.instances.getAuthString) combined with in-VPC network reach to the Redis port grants full data-plane read access to all keys on the Memorystore instance.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
{'principal': None}
CanReadCredential {'auth_string': None}
{'instance': None} ExposesCredential {'auth_string': None}
where
node_type(?auth_string) ==
Credential
node_type(?instance) == Cache
node_class(?principal) in [Identity, Compute]
?principal has in-VPC network reachability to ?instance.host on port 6379 or 6380
emit
| source type | Identity |
|---|---|
| target type | Cache |
| source | ?principal |
| target | ?instance |
| permissions | redis.instances.getAuthString |
| conditions | iam_permission network_reachability |
| state logic | ACTIVE when: (1) CanReadCredential input is ACTIVE (getAuthString permission held) (2) ExposesCredential input is ACTIVE (AUTH enabled on instance) AND (3) in-VPC network reachability to the Redis port is confirmed (VPC peering/Shared VPC, no blocking firewall rule on port 6379/6380). CONDITIONAL(network_reachability) when VPC topology is unresolved (e.g., peering unconfirmed, firewall rules not collected). CONDITIONAL(iam_permission) when CanReadCredential input is CONDITIONAL. BLOCKED if CanReadCredential is BLOCKED (IAM deny on getAuthString) or if a VPC firewall rule explicitly blocks port 6379/6380 from attacker's position to instance IP. NOTE: Do NOT apply key_permission gating. Memorystore does not support CMEK; data-at-rest encryption is Google-managed and transparent. |
Narrative
{principal.name} can retrieve the AUTH string for {instance.name} (redis.instances.getAuthString) and has network reach to the Redis port; it can authenticate via Redis AUTH and read all keys - including cached sessions, OAuth tokens, API keys, and connection strings stored in the cache.
Raw rule rules/derived/gcp/memorystore.yaml
id: gcp-memorystore-auth-string-grants-data-read
emits: CanReadData
description: Possession of the Redis AUTH string (retrieved via redis.instances.getAuthString) combined
with in-VPC network reach to the Redis port grants full data-plane read access to all keys on the Memorystore
instance.
match:
- - principal: null
- CanReadCredential
- auth_string: null
- - instance: null
- ExposesCredential
- auth_string: null
where:
- node_type(?auth_string) == Credential
- node_type(?instance) == Cache
- node_class(?principal) in [Identity, Compute]
- ?principal has in-VPC network reachability to ?instance.host on port 6379 or 6380
emit:
source_type: Identity
target_type: Cache
source: ?principal
target: ?instance
permissions:
- redis.instances.getAuthString
conditions:
- iam_permission
- network_reachability
state_logic: 'ACTIVE when: (1) CanReadCredential input is ACTIVE (getAuthString permission held) (2)
ExposesCredential input is ACTIVE (AUTH enabled on instance) AND (3) in-VPC network reachability to
the Redis port is confirmed (VPC peering/Shared VPC, no blocking firewall rule on port 6379/6380).
CONDITIONAL(network_reachability) when VPC topology is unresolved (e.g., peering unconfirmed, firewall
rules not collected). CONDITIONAL(iam_permission) when CanReadCredential input is CONDITIONAL. BLOCKED
if CanReadCredential is BLOCKED (IAM deny on getAuthString) or if a VPC firewall rule explicitly blocks
port 6379/6380 from attacker''s position to instance IP. NOTE: Do NOT apply key_permission gating.
Memorystore does not support CMEK; data-at-rest encryption is Google-managed and transparent.'
confidence: min(contributing_confidences) * 0.9
derived_from:
- '<CanReadCredential: principal -> AUTH string Credential>'
- '<ExposesCredential: instance -> AUTH string Credential>'
- '<network_reachability confirmation: principal IP -> instance.host:6379/6380>'
false_positive_note: "BOTH conditions must be satisfied for ACTIVE: (1) the principal holds redis.instances.getAuthString\
\ AND the instance has authEnabled=true (confirmed by the ExposesCredential input), AND (2) in-VPC\
\ network reach to port 6379 (plaintext) or 6380 (TLS) is confirmed by VPC topology analysis \u2014\
\ peering route exists, no VPC firewall rule blocks the traffic. When network reach is unresolved,\
\ emit as CONDITIONAL(network_reachability), not ACTIVE. AUTH does not protect against in-VPC malicious\
\ principals (per Google docs) \u2014 once the string is obtained, any in-VPC position can authenticate.\
\ This CanReadData edge implies full Redis read command access: reads (GET, SCAN, KEYS). Do NOT emit\
\ ExposedToInternet. Do NOT gate on key_permission."
narrative: "{principal.name} can retrieve the AUTH string for {instance.name} (redis.instances.getAuthString)\
\ and has network reach to the Redis port; it can authenticate via Redis AUTH and read all keys \u2014\
\ including cached sessions, OAuth tokens, API keys, and connection strings stored in the cache."