aws-elasticache-modify-usergroup-escalation
elasticache:ModifyUserGroup can add an attacker-controlled ACL User to a User Group that is already attached to a Redis/Valkey cluster. The attacker then authenticates as that user to the cluster with the user's effective ACL permissions (which may include allcommands/allkeys for full access). This bypasses the AUTH token and grants data-plane access via the ACL user.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
Group
?usergroup.provider_type == 'AWS::ElastiCache::UserGroup'
?principal has EFFECTIVE elasticache:ModifyUserGroup on ?usergroup ARN
?usergroup has ReferencedBy (or AttachedTo/MemberOf) a Redis/Valkey cache (collected via DescribeReplicationGroups UserGroupIds or DescribeServerlessCaches UserGroupId)
emit
| source type | Identity |
|---|---|
| target type | Group |
| source | ?principal |
| target | ?usergroup |
| permissions | elasticache:ModifyUserGroup elasticache:CreateUser |
| conditions | iam_permission scp_or_org_policy |
| state logic | CONDITIONAL(iam_permission) by default. Upgrade to ACTIVE only when the principal is confirmed to hold BOTH elasticache:ModifyUserGroup AND either: (a) control over an existing ACL User, or (b) EFFECTIVE elasticache:CreateUser permission. If only ModifyUserGroup is present, the attack requires the attacker to have a pre-existing controlled User, which must be verified separately. BLOCKED when an SCP or permission boundary explicitly denies elasticache:ModifyUserGroup on the target User Group ARN. The resulting data-plane access is CONDITIONAL(network_reachability) — the attacker must hold a VPC foothold and the user's ACL permissions gate which commands/keys are accessible. This CanModifyConfiguration edge models the User Group mutation capability; downstream rules or linchpins will derive CanReadData when network_reachability and the user's effective ACL scope are confirmed. |
Narrative
{principal.name} can call elasticache:ModifyUserGroup on {usergroup.name} to add an attacker-controlled ACL User to the group. Any Redis/Valkey cache cluster that has {usergroup.name} attached (such as {cache.name}) will then accept connections from that user with the user's effective ACL permissions. If the user has allcommands + allkeys ACL, the attacker gains full read/write access to the cache. If the user has limited permissions, the attacker can perform only those operations. Network reachability to the cache (port 6379) is still required.
Raw rule rules/derived/aws/elasticache.yaml
id: aws-elasticache-modify-usergroup-escalation
emits: CanModifyConfiguration
description: elasticache:ModifyUserGroup can add an attacker-controlled ACL User to a User Group that
is already attached to a Redis/Valkey cluster. The attacker then authenticates as that user to the cluster
with the user's effective ACL permissions (which may include allcommands/allkeys for full access). This
bypasses the AUTH token and grants data-plane access via the ACL user.
match:
- - principal: null
- HasPermission
- usergroup: null
where:
- generic_type(?usergroup) == Group
- ?usergroup.provider_type == 'AWS::ElastiCache::UserGroup'
- ?principal has EFFECTIVE elasticache:ModifyUserGroup on ?usergroup ARN
- ?usergroup has ReferencedBy (or AttachedTo/MemberOf) a Redis/Valkey cache (collected via DescribeReplicationGroups
UserGroupIds or DescribeServerlessCaches UserGroupId)
emit:
source_type: Identity
target_type: Group
source: ?principal
target: ?usergroup
permissions:
- elasticache:ModifyUserGroup
- elasticache:CreateUser
conditions:
- iam_permission
- scp_or_org_policy
state_logic: "CONDITIONAL(iam_permission) by default. Upgrade to ACTIVE only when the principal is confirmed\
\ to hold BOTH elasticache:ModifyUserGroup AND either: (a) control over an existing ACL User, or (b)\
\ EFFECTIVE elasticache:CreateUser permission. If only ModifyUserGroup is present, the attack requires\
\ the attacker to have a pre-existing controlled User, which must be verified separately. BLOCKED\
\ when an SCP or permission boundary explicitly denies elasticache:ModifyUserGroup on the target User\
\ Group ARN. The resulting data-plane access is CONDITIONAL(network_reachability) \u2014 the attacker\
\ must hold a VPC foothold and the user's ACL permissions gate which commands/keys are accessible.\
\ This CanModifyConfiguration edge models the User Group mutation capability; downstream rules or\
\ linchpins will derive CanReadData when network_reachability and the user's effective ACL scope are\
\ confirmed."
confidence: min(contributing_confidences) * 0.85
derived_from:
- ?principal CanModifyConfiguration ?usergroup (elasticache:ModifyUserGroup effective permission)
false_positive_note: "This rule applies only to Redis 6+ / Valkey clusters using ACL User Groups. Confirm\
\ that ?usergroup is actually attached to one or more cache clusters (DescribeReplicationGroups UserGroupIds\
\ or DescribeServerlessCaches UserGroupId). The attack requires that the principal either controls\
\ an existing User or can create a new User (elasticache:CreateUser permission). Check for both paths.\
\ If the User Group is attached to a cache but the principal has no way to create or control a User,\
\ emit CONDITIONAL(iam_permission) and note the missing Create permission. The resulting access is\
\ CONDITIONAL(network_reachability) \u2014 the attacker must reach the cache on port 6379 and be able\
\ to authenticate as the added User. Honor SCP denials on elasticache:ModifyUserGroup."
narrative: '{principal.name} can call elasticache:ModifyUserGroup on {usergroup.name} to add an attacker-controlled
ACL User to the group. Any Redis/Valkey cache cluster that has {usergroup.name} attached (such as
{cache.name}) will then accept connections from that user with the user''s effective ACL permissions.
If the user has allcommands + allkeys ACL, the attacker gains full read/write access to the cache.
If the user has limited permissions, the attacker can perform only those operations. Network reachability
to the cache (port 6379) is still required.'