背景
PR #56 のディープレビュー指摘 (B56-2)。ConsumedRequestStore による mutation の使い切り検証は導入したが、その適用範囲が単一ノード・単一プロセス寿命に閉じている。
問題
ConsumedRequestStore は実装自身が次を明記している。
- ノード再起動で記録を失う
- 別 replica は同じ署名をそれぞれ 1 回受理する
「CRDT なので同じ operation の重複には耐える」はこの経路には適用できない。各 replica は受信リクエストから同一の CRDT operation を再適用するのではなく、そのノードの author と現在の head を使って新しい operation を生成するためである。
したがって攻撃者は:
- 旧 update A を member 1 で使う
- 正規 update B が入る
- 同じ A を member 2 へ直接、または別 relay 経由で送る
- A が新しい operation として commit される
同一ノードでも再起動後に再度成立する。
現状の緩和(PR #56 時点)
- request ID は署名バイト列ではなく署名対象メッセージ + signer から導出しているので、ECDSA malleability (
s → n-s) による迂回は塞がっている
- 署名は operation / resource / timestamp / body digest に束縛されているので、別 content・別操作への転用はできない
- 鮮度窓 300 秒(RFC 9449 §11.1 / AWS SigV4 準拠)を超えた提示は弾かれる
残るのは上記の「鮮度窓の内に、記録を持たない別 replica へ提示する」経路である。
あるべき修正
- mutation に、signer が署名する stable な operation ID を持たせる
- その ID を CRDT / replicated state の一部として、Content Network 全体で dedup する
テスト観点
A → B → replay(A) が次のいずれでも成立しないこと:
- 別 member へ直接提示
- 別 relay 経由で提示
- ノード再起動後に提示
関連
🤖 Generated with Claude Code
https://claude.ai/code/session_01S8xhYR7ZuFkiFMS91NUW6c
背景
PR #56 のディープレビュー指摘 (B56-2)。
ConsumedRequestStoreによる mutation の使い切り検証は導入したが、その適用範囲が単一ノード・単一プロセス寿命に閉じている。問題
ConsumedRequestStoreは実装自身が次を明記している。「CRDT なので同じ operation の重複には耐える」はこの経路には適用できない。各 replica は受信リクエストから同一の CRDT operation を再適用するのではなく、そのノードの author と現在の head を使って新しい operation を生成するためである。
したがって攻撃者は:
同一ノードでも再起動後に再度成立する。
現状の緩和(PR #56 時点)
s → n-s) による迂回は塞がっている残るのは上記の「鮮度窓の内に、記録を持たない別 replica へ提示する」経路である。
あるべき修正
テスト観点
A → B → replay(A)が次のいずれでも成立しないこと:関連
🤖 Generated with Claude Code
https://claude.ai/code/session_01S8xhYR7ZuFkiFMS91NUW6c