From 1fa5360a210b4b820441fdbc6f5dfbbb9eaf14f3 Mon Sep 17 00:00:00 2001 From: tv Date: Sun, 8 Nov 2026 21:46:41 +0000 Subject: screen: signatures required as the policy a change came under says Review 3, R1: what a node received was vouched for only while its own document's policy required signatures. A joiner's first sync, and every node's message bringing `required`, went in by the rules alone: a malicious first peer could plant changes under other members' actors at their next seqs, their real ones then failing as duplicates for good. The signatures a message carries are always offered now, and the screen always has them: a change waits for one where the policy at the heads it is judged at requires it (rules::Reads::required, read once per heads), whatever the receiving document holds. Changes written under a policy not requiring signatures wait for none, as on every other node; the check for forged changes runs always. Changes waiting for a signature are judged again whenever signatures come. The test of signatures required now takes the history into an empty document; a new one takes changes written under a policy not requiring them without any. --- src/state/host.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/state') diff --git a/src/state/host.rs b/src/state/host.rs index 01cbaa2..7b2eb07 100644 --- a/src/state/host.rs +++ b/src/state/host.rs @@ -570,7 +570,6 @@ impl Host for AppState { tokio::task::spawn_blocking(move || { let result = { let mut replica = state.doc.blocking_write(); - let policy = crate::access::policy::of(&replica.doc); // Judged first (`access::screen`), whether this document has a policy // yet or not. let result = { @@ -582,7 +581,7 @@ impl Host for AppState { epoch_seq, change.raw_bytes(), &state.screening, - policy.required().then_some(&mut replica.signatures), + Some(&mut replica.signatures), &mut crate::document::PatchLog::inactive(), ) .map(|_| ()) -- cgit v1.3.1