Skip to content

[critical] Durability pull merges unscoped, unprovenanced peer-asserted components #104

Description

@mbertschler

Summary

The durability metadata pull merges peer-asserted vector components into the local destination_run_ids table with almost no scoping, and the merged rows later gate squirrel offload (deletion). A compromised or buggy peer holding a valid token can therefore make the local node believe content is durable on a destination it cannot itself observe — and then offload deletes the local copy.

Where

  • sync/durability.gopullDurability / validateComponent (checks only: destination non-empty, origin a valid node name, run > 0)
  • store/destination_run_ids.goUpsertDestinationRunID (monotonic merge, no source tagging)
  • offload/gate.go — reads ListDestinationRunIDs with no per-source distinction

Scenario

A volume requires ["nas", "offsite"]. Only the NAS pushes to offsite, so the laptop's only evidence about offsite is the post-sync pull from the NAS. A compromised NAS returns a component {Destination: "offsite", OriginNode: <laptop>, OriginRun: >= current} for every origin. The laptop merges it; the gate's offsite vector now "covers" everything; squirrel offload deletes local bytes that exist only on the compromised NAS.

Because the merge is keyed purely by destination name and is monotonic, a peer can also inflate a component for a target the laptop verifies itself (e.g. nas) above the laptop's own verified value — corrupting directly-verified evidence.

Fix shape

Consistent with the trusted-peer design stance, contain the blast radius:

  1. In pullDurability, drop any component whose destination is not a peer-only target named in this volume's offload_requires (and never accept a component for a destination the local node syncs directly — those advance only via local verified AdvanceDestinationVector).
  2. Record pulled evidence tagged with the asserting peer (a source column / separate table), so the gate can weigh it as a distinct, revocable class and the audit trail can answer "which evidence gated this offload" (currently pulled vs locally-verified rows are indistinguishable).

This was flagged at PR #99 review time as inherent to the trusted-peer model; the audit traced it to a concrete data-loss chain, so it warrants the scoping fix now that offload_requires exists.

Adversarial audit of offload-v1 (auditor C C-1, auditor D F7b).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdata-lossCould cause silent data losssecuritySecurity / data-integrity finding

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions