aws-memorydb-update-user-yields-data-read

memorydb:UpdateUser overwrites an ACL user password (CanModify on Credential); attacker with VPC reach can then authenticate and read cluster data.

derived aws emits CanReadData

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} CanModify {'aclUser': None} {'aclUser': None} CredentialsFor {'cluster': None}

where

node_type(?aclUser) == Credential ?aclUser.provider_type == 'memorydb_acl_user' node_type(?cluster) == Cache ?cluster.provider == 'aws'

optional

Present → upgrade the emitted state; absent → downgrade (not a hard requirement).

{'principal': None} CanNetworkReach {'cluster': None}

emit

source typeIdentity
target typeCache
source?principal
target?cluster
permissionsmemorydb:UpdateUser
conditionsnetwork_reachability
state logicif matched(optional[0]): ACTIVE — network reach to the cluster is already derived and confirmed; the principal can reset the ACL user password and authenticate immediately. else: CONDITIONAL(network_reachability) — the cluster endpoint is always VPC-private; confirm a VPC foothold (Compute in the same VPC, VPN/Direct Connect, or VPC peering) before upgrading to ACTIVE.

Narrative

{principal.name} can overwrite the password of ACL user {aclUser.name} (memorydb:UpdateUser), whose credentials authenticate to MemoryDB cluster {cluster.name}; with VPC network access to the cluster endpoint, {principal.name} can read and write Redis data on {cluster.name}.

Raw rule rules/derived/aws/memorydb.yaml

id: aws-memorydb-update-user-yields-data-read
emits: CanReadData
description: memorydb:UpdateUser overwrites an ACL user password (CanModify on Credential); attacker with
  VPC reach can then authenticate and read cluster data.
match:
- - principal: null
  - CanModify
  - aclUser: null
- - aclUser: null
  - CredentialsFor
  - cluster: null
optional:
- - principal: null
  - CanNetworkReach
  - cluster: null
where:
- node_type(?aclUser) == Credential
- ?aclUser.provider_type == 'memorydb_acl_user'
- node_type(?cluster) == Cache
- ?cluster.provider == 'aws'
emit:
  source_type: Identity
  target_type: Cache
  source: ?principal
  target: ?cluster
  permissions:
  - memorydb:UpdateUser
  conditions:
  - network_reachability
  state_logic: "if matched(optional[0]): ACTIVE \u2014 network reach to the cluster is already derived\
    \ and confirmed; the principal can reset the ACL user password and authenticate immediately. else:\
    \ CONDITIONAL(network_reachability) \u2014 the cluster endpoint is always VPC-private; confirm a VPC\
    \ foothold (Compute in the same VPC, VPN/Direct Connect, or VPC peering) before upgrading to ACTIVE."
  confidence: min(contributing_confidences) * 0.85
  derived_from:
  - '<CanModify edge_id: ?principal -> ?aclUser>'
  - '<CredentialsFor edge_id: ?aclUser -> ?cluster>'
  - '[optional] <CanNetworkReach edge_id: ?principal -> ?cluster>'
  false_positive_note: "Only emit when the CanModify edge is backed by memorydb:UpdateUser on the specific\
    \ ACL user (provider_type memorydb_acl_user) whose CredentialsFor link targets this cluster. Do NOT\
    \ emit for DescribeUsers (read-only; produces no CanModify). Do NOT emit CanImpersonate or CanAssume\
    \ \u2014 ACL users are not IAM identities; data-plane access is not IAM role assumption. Downgrade\
    \ confidence when the ACL user's access string is known to be read-only or key-restricted. CONDITIONAL(network_reachability)\
    \ is mandatory \u2014 MemoryDB is always VPC-private. The optional CanNetworkReach clause structurally\
    \ enforces the network gate rather than relying on prose alone."
  narrative: '{principal.name} can overwrite the password of ACL user {aclUser.name} (memorydb:UpdateUser),
    whose credentials authenticate to MemoryDB cluster {cluster.name}; with VPC network access to the
    cluster endpoint, {principal.name} can read and write Redis data on {cluster.name}.'
move · open · esc close