aws-memorydb-snapshot-exfil
memorydb:CopySnapshot exports cluster snapshot to S3; attacker-accessible bucket yields full data exfiltration.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?snapshot) ==
Snapshot
?snapshot.provider_type == 'AWS::MemoryDB::Snapshot'
?principal has EFFECTIVE memorydb:CopySnapshot on ?snapshot ARN
emit
| source type | Identity |
|---|---|
| target type | Snapshot |
| source | ?principal |
| target | ?snapshot |
| permissions | memorydb:CopySnapshot |
| conditions | iam_permission scp_or_org_policy resource_policy key_permission |
| state logic | CONDITIONAL(resource_policy): the principal can call memorydb:CopySnapshot to export the snapshot to an S3 bucket. However, the destination bucket must be attacker-accessible (principal controls the bucket, or bucket policy allows writes from the principal's account, or cross-account S3 write edge exists). Upgrade to ACTIVE only when the destination bucket is confirmed attacker-accessible. CONDITIONAL(key_permission) when the snapshot is encrypted with a CMK: the CopySnapshot call succeeds, but reading the snapshot content in S3 requires kms:Decrypt on the CMK. BLOCKED when an SCP or permission boundary denies memorydb:CopySnapshot. |
Narrative
{principal.name} can call memorydb:CopySnapshot to export the MemoryDB snapshot {snapshot.name} to an S3 bucket as a complete data dump. The snapshot contains all in-memory cluster data at snapshot time, including any cached application secrets, session tokens, API keys, or database credentials. If the destination S3 bucket is attacker-accessible, {principal.name} can download and parse the snapshot offline to extract all cached data without ever connecting to the live cluster.
Raw rule rules/derived/aws/memorydb.yaml
id: aws-memorydb-snapshot-exfil
emits: CanExfiltrate
description: memorydb:CopySnapshot exports cluster snapshot to S3; attacker-accessible bucket yields full
data exfiltration.
match:
- - principal: null
- HasPermission
- snapshot: null
where:
- node_type(?snapshot) == Snapshot
- ?snapshot.provider_type == 'AWS::MemoryDB::Snapshot'
- ?principal has EFFECTIVE memorydb:CopySnapshot on ?snapshot ARN
emit:
source_type: Identity
target_type: Snapshot
source: ?principal
target: ?snapshot
permissions:
- memorydb:CopySnapshot
conditions:
- iam_permission
- scp_or_org_policy
- resource_policy
- key_permission
state_logic: 'CONDITIONAL(resource_policy): the principal can call memorydb:CopySnapshot to export the
snapshot to an S3 bucket. However, the destination bucket must be attacker-accessible (principal controls
the bucket, or bucket policy allows writes from the principal''s account, or cross-account S3 write
edge exists). Upgrade to ACTIVE only when the destination bucket is confirmed attacker-accessible.
CONDITIONAL(key_permission) when the snapshot is encrypted with a CMK: the CopySnapshot call succeeds,
but reading the snapshot content in S3 requires kms:Decrypt on the CMK. BLOCKED when an SCP or permission
boundary denies memorydb:CopySnapshot.'
confidence: min(contributing_confidences) * 0.75
derived_from:
- ?principal HasPermission ?snapshot (memorydb:CopySnapshot effective permission)
false_positive_note: "The destination S3 bucket is the critical gate. memorydb:CopySnapshot's TargetS3BucketName\
\ parameter specifies where the snapshot is written. The attacker must have write access (s3:PutObject)\
\ on the bucket to retrieve the snapshot file. Do NOT emit ACTIVE without confirming the bucket is\
\ attacker-accessible (in the attacker's account, or the bucket policy allows the principal's account\
\ to write). For encrypted snapshots (KmsKeyId is non-empty), the snapshot is encrypted with that\
\ CMK; the attacker needs kms:Decrypt on the key to read the unencrypted snapshot file. AWS-managed\
\ key (default aws/memorydb) is available per-account; custom CMKs require explicit key-grant evaluation.\
\ This rule requires an existing snapshot \u2014 memorydb:CreateSnapshot must have been called first\
\ (or a snapshot is pre-existing). The snapshot itself is the attack target, not the cluster; a snapshot\
\ can persist long after the cluster is deleted. This rule is conservative (Phase-6 low-relevance\
\ guidance: 1-3 rules). Snapshot exfil is powerful but requires two permissions (CopySnapshot + S3\
\ access) and is more complex than the ACL-swap path."
narrative: '{principal.name} can call memorydb:CopySnapshot to export the MemoryDB snapshot {snapshot.name}
to an S3 bucket as a complete data dump. The snapshot contains all in-memory cluster data at snapshot
time, including any cached application secrets, session tokens, API keys, or database credentials.
If the destination S3 bucket is attacker-accessible, {principal.name} can download and parse the snapshot
offline to extract all cached data without ever connecting to the live cluster.'