gcp-filestore-snapshot-exfiltrate
A principal holding file.snapshots.get in the source project plus file.instances.create or file.instances.update in an attacker-controlled destination project can restore a Filestore snapshot to the destination, exfiltrating all data. Snapshots are point-in-time copies of a share and can be restored cross-project exactly as with backups, making this an equally viable cross-boundary data exfiltration path.
match
A conjunctive graph pattern. Variables (?x) bind node ids; every clause must hold.
HasPermission file.snapshots.get
{'snapshot': None} LocatedIn {'source_project': None}
{'principal': None} HasPermission file.instances.create
where
Snapshot
?snapshot.sourceInstance references ?source_instance: node_type(?source_instance) == FileStorage
the third HasPermission edge (?principal -> file.instances.create) is scoped to ?dest_project
?principal controls ?dest_project (or is a member of a compromised account there)
?dest_project != ?source_project
emit
| source type | Identity |
|---|---|
| target type | Snapshot |
| source | ?principal |
| target | ?snapshot |
| permissions | file.snapshots.get file.instances.create file.instances.update |
| conditions | iam_permission |
| state logic | ACTIVE when both conditions hold: (a) file.snapshots.get is effective in the source project AND (b) file.instances.create or file.instances.update is effective in the destination project at the same principal scope, AND the destination project is under attacker control. CONDITIONAL(iam_permission) if one permission is confirmed but the other scope is unresolved. BLOCKED if an IAM deny policy denies either permission at the effective scope. |
Narrative
{principal.name} holds file.snapshots.get in {source_project.name} and file.instances.create in {dest_project.name}, and can restore the {snapshot.name} snapshot to an instance in the destination project, exfiltrating all data from the original {source_instance.name} Filestore instance.
Raw rule rules/derived/gcp/filestore.yaml
id: gcp-filestore-snapshot-exfiltrate
emits: CanExfiltrate
description: A principal holding file.snapshots.get in the source project plus file.instances.create or
file.instances.update in an attacker-controlled destination project can restore a Filestore snapshot
to the destination, exfiltrating all data. Snapshots are point-in-time copies of a share and can be
restored cross-project exactly as with backups, making this an equally viable cross-boundary data exfiltration
path.
match:
- - principal: null
- HasPermission
- file.snapshots.get
- - snapshot: null
- LocatedIn
- source_project: null
- - principal: null
- HasPermission
- file.instances.create
where:
- node_type(?snapshot) == Snapshot
- '?snapshot.sourceInstance references ?source_instance: node_type(?source_instance) == FileStorage'
- the third HasPermission edge (?principal -> file.instances.create) is scoped to ?dest_project
- ?principal controls ?dest_project (or is a member of a compromised account there)
- ?dest_project != ?source_project
emit:
source_type: Identity
target_type: Snapshot
source: ?principal
target: ?snapshot
permissions:
- file.snapshots.get
- file.instances.create
- file.instances.update
conditions:
- iam_permission
state_logic: 'ACTIVE when both conditions hold: (a) file.snapshots.get is effective in the source project
AND (b) file.instances.create or file.instances.update is effective in the destination project at
the same principal scope, AND the destination project is under attacker control. CONDITIONAL(iam_permission)
if one permission is confirmed but the other scope is unresolved. BLOCKED if an IAM deny policy denies
either permission at the effective scope.'
confidence: 0.95 when both permissions confirmed and projects verified as distinct
derived_from:
- gcp-filestore-snapshot-exfiltrate
false_positive_note: 'Both permissions are REQUIRED: read access to the snapshot in source project +
write/create access to instances in destination project at the same principal scope. Snapshots are
point-in-time copies and can be restored just like backups. Confirm the principal holds both permissions
at the right scopes and the destination project is controlled by the attacker. All data in the snapshot
is exfiltrated without IAM filtering. If destination-project permission is unresolved, do not emit
as ACTIVE.'
narrative: '{principal.name} holds file.snapshots.get in {source_project.name} and file.instances.create
in {dest_project.name}, and can restore the {snapshot.name} snapshot to an instance in the destination
project, exfiltrating all data from the original {source_instance.name} Filestore instance.'