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.

derived aws emits CanExfiltrate

match

A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.

{'principal': None} HasPermission {'perm': None}

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 typeIdentity
target typeSnapshot
source?principal
target<Neptune cluster snapshot (Snapshot)>
permissionsrds:ModifyDBClusterSnapshotAttribute
conditionsiam_permission key_permission
state logicACTIVE 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."
move · open · esc close