Cyphrme / Cyphrme/Cyphr

Witness sync accepts a replayed authority response as current

Open
#152 0 comments 0 reactions 0 assignees View on GitHub
security tech-debt
Dominant language
Rust
Stars
3
Forks
0
Avg merge
1d 42m
Merged PRs (30d)
11

Description

A witness that pulls state from an authority it follows now decides whether to accept a response by comparing its own independently-verified resulting state against the authority's independently-signed report. That closes every way a response can be *altered*: entries cannot be substituted, truncated, emptied, or served for a different principal without detection, because acceptance no longer depends on reading the response against itself.

It does not close **replay**, and no integrity check can, because replay falsifies nothing.

## The attack

The comparison authenticates the *pairing* of local state and signed report. It does not authenticate the report's **currency**. A report the authority genuinely signed at a moment when its tip equalled the witness's current state will match that state forever.

So an on-path party retains one response from such a moment and returns it on every subsequent poll. The signature is genuine, the report is canonical, the principal is correct, and the state comparison passes because the report describes exactly the state the witness is in. The response carries no entries, so the outcome is "already up to date." The authority meanwhile advances without limit, and the witness reports health indefinitely.

The required response is not rare or difficult to obtain. It is the steady-state response every healthy polling witness receives on every cycle where nothing has changed, so an observer on the path always holds a fresh one.

Demonstrated behaviour, with the authority advancing to a second commit after the retained response was captured:

```
sync (honest, catch up) = Synced { applied: 1, rejected: 0 }
sync (honest, steady state) = UpToDate <- response retained here
authority advances -> commit_count = 2
sync (replayed) = UpToDate
sync (replayed) = UpToDate
sync (replayed) = UpToDate
witness tip = 200, commit_count = 1 (authority holds 2)
```

No warning is emitted on any path.

## Why this matters more than simply blocking the connection

An adversary who drops traffic also pins the witness at a stale state — but that surfaces as an unreachable upstream, which is loud and distinguishable. Replay surfaces as **health**.

Once modification is closed, detection is the only remaining thing to defeat, and replay defeats it precisely. The success outcome now carries a count of rejected entries, added specifically so that a future consumer could judge whether a witness is usefully current. A replayed response produces a clean up-to-date result with nothing rejected, which no such consumer can flag.

## Why it is not fixed at the sync layer

Closing replay requires a freshness or monotonicity property, and this project's trust model holds that a witness's currency is non-monotone and that a signed wall-clock timestamp is not the cure. Choosing the mechanism is a protocol decision, not a change to the sync path.

This is the same question already open as #139, which asks what a witness attestation asserts about currency. That issue and this one are the same problem seen from opposite directions: #139 from what an attestation is entitled to claim, this from what an adversary achieves when nothing constrains it. Resolving #139 should determine the fix here, and a fix chosen independently would very likely be the wrong one.

## What was done instead

The affected module previously documented general withholding closure, in terms asserting there was no wire field left to falsify. That claim is false, and a false security comment is the defect this same work already had to correct twice. The documentation now states what is actually enforced and names currency as the missing property, so the next reader is not misled about the guarantee.

## Resolving this

Gated on #139. Once currency has a defined meaning, the cure is likely one of a small number of shapes — a witness-supplied challenge the authority must incorporate, a monotone counter the witness tracks across polls, or a bound on acceptable staleness derived from something the witness itself produces. Each has different costs and different implications for a witness with no signing identity, and none should be chosen before the specification settles what an attestation asserts.

Related: #139, #141.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with issue #139, then read the affected module's updated documentation about withholding and currency. Define what witness currency means before choosing a protocol mechanism; done means an agreed specification and implementation that prevents replay without relying on an authority timestamp or witness signing identity.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
distributed-systems, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.