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.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
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 type | Identity |
|---|---|
| target type | Cache |
| source | ?principal |
| target | ?cluster |
| permissions | memorydb:UpdateUser |
| conditions | network_reachability |
| state logic | if 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}.'