aws-neptune-snapshot-exfil
Principal with rds:ModifyDBClusterSnapshotAttribute permission on a Neptune cluster snapshot can share it cross-account or make it publicly restorable, enabling full graph data exfiltration.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
where
?perm.action == 'rds:ModifyDBClusterSnapshotAttribute'
?perm.resource_type == 'AWS::Neptune::DBClusterSnapshot'
target snapshot is of type SnapshotType: manual (automated snapshots cannot be shared)
emit
| source type | Identity |
|---|---|
| target type | Snapshot |
| source | ?principal |
| target | <Neptune cluster snapshot (Snapshot)> |
| permissions | rds:ModifyDBClusterSnapshotAttribute |
| conditions | iam_permission key_permission |
| state logic | ACTIVE when the principal has effective rds:ModifyDBClusterSnapshotAttribute on the snapshot ARN AND the snapshot is a manual snapshot (SnapshotType: manual) AND the snapshot is NOT CMK-encrypted (service-managed encryption does not require a key grant from the restoring account). CONDITIONAL(key_permission) when the snapshot is encrypted with a customer-managed KMS key (CMK) — the exfiltration is only completable if the target account is also granted kms:Decrypt / kms:CreateGrant on the CMK. BLOCKED if an SCP or IAM boundary denies neptune:ModifyDBClusterSnapshotAttribute. The severity is highest when ValuesToAdd=[all] (public — any AWS account can restore); lower but still high when ValuesToAdd=[<specific accountId>] (targeted share). |
Narrative
{principal.name} can call rds:ModifyDBClusterSnapshotAttribute on Neptune cluster snapshot {snapshot.name} to set restore access to any AWS account or to a specific attacker-controlled account; the recipient account can then call rds:RestoreDBClusterFromSnapshot to create a full copy of all graph data (vertices, edges, properties) - a complete offline data exfiltration without compromising the live cluster.
Raw rule rules/derived/aws/neptune.yaml
id: aws-neptune-snapshot-exfil
emits: CanExfiltrate
description: Principal with rds:ModifyDBClusterSnapshotAttribute permission on a Neptune cluster snapshot
can share it cross-account or make it publicly restorable, enabling full graph data exfiltration.
match:
- - principal: null
- HasPermission
- perm: null
where:
- ?perm.action == 'rds:ModifyDBClusterSnapshotAttribute'
- ?perm.resource_type == 'AWS::Neptune::DBClusterSnapshot'
- 'target snapshot is of type SnapshotType: manual (automated snapshots cannot be shared)'
emit:
source_type: Identity
target_type: Snapshot
source: ?principal
target: <Neptune cluster snapshot (Snapshot)>
permissions:
- rds:ModifyDBClusterSnapshotAttribute
conditions:
- iam_permission
- key_permission
derived_from:
- HasPermission(?principal, ?perm)
state_logic: "ACTIVE when the principal has effective rds:ModifyDBClusterSnapshotAttribute on the snapshot\
\ ARN AND the snapshot is a manual snapshot (SnapshotType: manual) AND the snapshot is NOT CMK-encrypted\
\ (service-managed encryption does not require a key grant from the restoring account). CONDITIONAL(key_permission)\
\ when the snapshot is encrypted with a customer-managed KMS key (CMK) \u2014 the exfiltration is\
\ only completable if the target account is also granted kms:Decrypt / kms:CreateGrant on the CMK.\
\ BLOCKED if an SCP or IAM boundary denies neptune:ModifyDBClusterSnapshotAttribute. The severity\
\ is highest when ValuesToAdd=[all] (public \u2014 any AWS account can restore); lower but still high\
\ when ValuesToAdd=[<specific accountId>] (targeted share)."
false_positive_note: "Only manual Neptune cluster snapshots (SnapshotType: manual) can be shared via\
\ ModifyDBClusterSnapshotAttribute. Automated snapshots cannot be directly shared \u2014 do not emit\
\ for automated snapshots. For CMK-encrypted snapshots, the target account must also receive a KMS\
\ key grant; without it the RestoreDBClusterFromSnapshot call fails \u2014 downgrade to CONDITIONAL(key_permission)\
\ and note the CMK ARN from the snapshot's KmsKeyId field. Distinguish ValuesToAdd=[all] (public \u2014\
\ highest severity) from ValuesToAdd=[<accountId>] (targeted share \u2014 still high severity but\
\ scoped to one account). An existing ModifyDBClusterSnapshotAttribute grant with AttributeValues\
\ already containing \"all\" or specific accountIds means the snapshot is ALREADY shared; emit with\
\ ACTIVE on the shared state, not just on the sharing capability of the principal."
narrative: "{principal.name} can call rds:ModifyDBClusterSnapshotAttribute on Neptune cluster snapshot\
\ {snapshot.name} to set restore access to any AWS account or to a specific attacker-controlled account;\
\ the recipient account can then call rds:RestoreDBClusterFromSnapshot to create a full copy of all\
\ graph data (vertices, edges, properties) \u2014 a complete offline data exfiltration without compromising\
\ the live cluster."