aws-redshift-snapshot-cross-account-exfil
redshift:AuthorizeSnapshotAccess grants another AWS account the ability to restore a cluster snapshot, exfiltrating a full copy of warehouse data to that account.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
node_type(?snapshot) ==
Snapshot
?snapshot.provider_type == 'AWS::Redshift::ClusterSnapshot'
?principal has EFFECTIVE redshift:AuthorizeSnapshotAccess on ?snapshot ARN
emit
| source type | Identity |
|---|---|
| target type | Snapshot |
| source | ?principal |
| target | ?snapshot |
| permissions | redshift:AuthorizeSnapshotAccess |
| conditions | iam_permission scp_or_org_policy |
| state logic | ACTIVE when redshift:AuthorizeSnapshotAccess is confirmed EFFECTIVE on the snapshot ARN (identity-based policy + no SCP deny). CONDITIONAL(iam_permission) when an SCP or permission boundary may restrict the action but isn't resolved. BLOCKED by an explicit SCP deny on redshift:AuthorizeSnapshotAccess. A successful AuthorizeSnapshotAccess does not automatically restore the cluster — it grants the permission; the exfiltration is realized when the target account calls RestoreFromClusterSnapshot. Emit CanExfiltrate here for the authorization capability; note the restore step as implicit. |
Narrative
{principal.name} can share the Redshift snapshot {snapshot.name} with an external AWS account (redshift:AuthorizeSnapshotAccess), enabling that account to restore a full copy of the cluster's data - a complete warehouse exfiltration.
Raw rule rules/derived/aws/redshift.yaml
id: aws-redshift-snapshot-cross-account-exfil
emits: CanExfiltrate
description: redshift:AuthorizeSnapshotAccess grants another AWS account the ability to restore a cluster
snapshot, exfiltrating a full copy of warehouse data to that account.
match:
- - principal: null
- HasPermission
- snapshot: null
where:
- node_type(?snapshot) == Snapshot
- ?snapshot.provider_type == 'AWS::Redshift::ClusterSnapshot'
- ?principal has EFFECTIVE redshift:AuthorizeSnapshotAccess on ?snapshot ARN
emit:
source_type: Identity
target_type: Snapshot
source: ?principal
target: ?snapshot
permissions:
- redshift:AuthorizeSnapshotAccess
conditions:
- iam_permission
- scp_or_org_policy
state_logic: "ACTIVE when redshift:AuthorizeSnapshotAccess is confirmed EFFECTIVE on the snapshot ARN\
\ (identity-based policy + no SCP deny). CONDITIONAL(iam_permission) when an SCP or permission boundary\
\ may restrict the action but isn't resolved. BLOCKED by an explicit SCP deny on redshift:AuthorizeSnapshotAccess.\
\ A successful AuthorizeSnapshotAccess does not automatically restore the cluster \u2014 it grants\
\ the permission; the exfiltration is realized when the target account calls RestoreFromClusterSnapshot.\
\ Emit CanExfiltrate here for the authorization capability; note the restore step as implicit."
confidence: min(contributing_confidences) * 0.95
derived_from:
- ?principal HasPermission ?snapshot (redshift:AuthorizeSnapshotAccess effective permission)
false_positive_note: "AuthorizeSnapshotAccess grants a SPECIFIC account the restore permission; it is\
\ not an open wildcard grant. The target account must then call RestoreFromClusterSnapshot, incurring\
\ Redshift compute costs and typically appearing in CloudTrail. The snapshot must exist (not already\
\ deleted via automated retention). KMS-encrypted snapshots (cluster uses a CMK) require the target\
\ account to also be granted kms:Decrypt on the CMK \u2014 without it, RestoreFromClusterSnapshot\
\ fails (CONDITIONAL(key_permission) on the exfil if the snapshot's CMK grant is unresolved)."
narrative: "{principal.name} can share the Redshift snapshot {snapshot.name} with an external AWS account\
\ (redshift:AuthorizeSnapshotAccess), enabling that account to restore a full copy of the cluster's\
\ data \u2014 a complete warehouse exfiltration."