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.

derived gcp emits CanReadData

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 typeIdentity
target typeCache
source?principal
target?instance
permissionsredis.instances.getAuthString
conditionsiam_permission network_reachability
state logicACTIVE 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."
move · open · esc close