gcp-memorystore-get-auth-string-exposes-credential
redis.instances.getAuthString retrieves the Redis AUTH string (UUID), which is the shared credential granting full Redis data-plane access to any in-VPC client that possesses it. This is the Memorystore "master key" credential grab.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?instance) ==
Cache
node_type(?auth_string) == Credential
?instance.authEnabled == true
emit
| source type | Cache |
|---|---|
| target type | Credential |
| source | ?instance |
| target | ?auth_string |
| permissions | redis.instances.getAuthString |
| conditions | iam_permission |
| state logic | ACTIVE when: the CanReadCredential input is ACTIVE (redis.instances.getAuthString permission held) AND instance.authEnabled is true (the AUTH string is meaningful only when AUTH is enabled). CONDITIONAL(iam_permission) when the CanReadCredential input is CONDITIONAL. BLOCKED if the CanReadCredential input is BLOCKED (IAM deny on getAuthString). Do NOT emit if instance.authEnabled is false — the AUTH string is not the access control mechanism when AUTH is disabled (use gcp-memorystore-no-auth- data-access instead). |
Narrative
{instance.name} exposes the Redis AUTH string (UUID) credential. Any principal holding redis.instances.getAuthString can retrieve it via the Memorystore API; any in-VPC client that possesses this string can authenticate to {instance.name} and access all Redis keys.
Raw rule rules/derived/gcp/memorystore.yaml
id: gcp-memorystore-get-auth-string-exposes-credential
emits: ExposesCredential
description: redis.instances.getAuthString retrieves the Redis AUTH string (UUID), which is the shared
credential granting full Redis data-plane access to any in-VPC client that possesses it. This is the
Memorystore "master key" credential grab.
match:
- - instance: null
- Contains
- auth_string: null
where:
- node_type(?instance) == Cache
- node_type(?auth_string) == Credential
- ?instance.authEnabled == true
emit:
source_type: Cache
target_type: Credential
source: ?instance
target: ?auth_string
permissions:
- redis.instances.getAuthString
conditions:
- iam_permission
state_logic: "ACTIVE when: the CanReadCredential input is ACTIVE (redis.instances.getAuthString permission\
\ held) AND instance.authEnabled is true (the AUTH string is meaningful only when AUTH is enabled).\
\ CONDITIONAL(iam_permission) when the CanReadCredential input is CONDITIONAL. BLOCKED if the CanReadCredential\
\ input is BLOCKED (IAM deny on getAuthString). Do NOT emit if instance.authEnabled is false \u2014\
\ the AUTH string is not the access control mechanism when AUTH is disabled (use gcp-memorystore-no-auth-\
\ data-access instead)."
confidence: min(contributing_confidences) * 0.95
derived_from:
- '<Contains edge: instance -> AUTH string Credential>'
- <instance.authEnabled == true>
false_positive_note: "Only emit when AUTH is enabled on the instance (authEnabled=true). When AUTH is\
\ disabled, the AUTH string is irrelevant \u2014 any in-VPC client already has full access without\
\ credentials. The ExposesCredential edge here documents the control-plane credential-grab path; it\
\ does NOT by itself yield data access \u2014 the attacker must also have network reach to port 6379/6380,\
\ which is modeled separately by gcp-memorystore-auth-string-grants-data-read and gcp-memorystore-auth-string-grants-data-write.\
\ Do NOT apply a key_permission gate: Memorystore does not use CMEK. Never emit ExposedToInternet."
narrative: '{instance.name} exposes the Redis AUTH string (UUID) credential. Any principal holding redis.instances.getAuthString
can retrieve it via the Memorystore API; any in-VPC client that possesses this string can authenticate
to {instance.name} and access all Redis keys.'