本文へ移動

Radicle のノード間通信が全バージョンで平文、private リポジトリは使用停止が推奨

ノード間通信が暗号化も認証もされておらず、経路上から private リポジトリの中身が読める。自前でノードを動かしている運用者向けに、完全性と機密性の切り分け、seeding を止める手順、修正が破壊的になる理由をまとめた。

Radicle のノード間通信は暗号化されていない。これまでにリリースされた全バージョンが対象で、二つのノードの経路上にいる者は、やり取りされるデータを平文で読める。Radicle 側は、修正版のリリース前にこれを公表した。自前でノードを動かして private リポジトリを同期させているなら、今日やることは seeding の停止と、すでに送ったものを漏洩として扱う判断になる。

署名は改竄を止めるが、中身は隠さない

Signed References は、経路上の攻撃者が転送中のオブジェクトを書き換えた場合、それを検知する。公表文によれば、二つの欠陥はどちらも node transport 層にあり、リポジトリのデータモデルにはない。Git オブジェクトと signed references は従来どおり storage 層で検証され、攻撃者がコードや identity を偽造することはできない。

残るのは読み取りだ。公表文は主な懸念を情報漏洩、つまり経路上の攻撃者が転送中のオブジェクトを読むことだとしている。public リポジトリでは情報漏洩の懸念は小さいとされ、private リポジトリでは転送時の暗号化が不可欠だとされる。影響の分かれ目はリポジトリの公開設定であって、ノードの設定ではない。

二つの欠陥が組み合わさると、全体の fetch まで広がる

一つ目は平文転送で、Konstantinos Maninakis が2026年6月24日に報告した。二つ目は接続 handshake の peer authentication が壊れていることで、攻撃者は自分のものではない Node ID を提示してノードに接続できる。こちらは cryptocode が2026年8月12日に報告し、Radicle 側は upstream に修正を提案している。private リポジトリは allow-list された Node ID にしか共有されないため、allow-list 上の Node ID を偽装できる攻撃者は、経路上にいなくても private リポジトリを直接 fetch できる。

なりすまし単体は、見た目より悪用が難しい。allow-list された Node ID を偽装するには、まずその ID を知る必要がある。allow-list は公開されていないので、経路の外にいる攻撃者は推測するしかない。

二つが揃うと条件が変わる。経路上の攻撃者には接続の両端の Node ID が見え、通常はその両方が allow-list に載っている。監視している間のやり取りを読み、見た Node ID を使って任意のタイミングでリポジトリ全体を fetch できる。現実的な脅威は自分のノードと同期先ノードの間の経路にいる者で、設定でも allow-list でも防げないと公表文は書いている。

経路上の盗聴と、経路外からのなりすましを分ける

サマリーが「主な懸念」とするのは、平文転送によって経路上の攻撃者がやり取り中のオブジェクトを読むことだ。詳細節が説明する二つ目の欠陥は別の条件で、allow-list の Node ID を知る攻撃者なら、経路上にいなくてもその ID を偽装して private リポジトリを直接 fetch できる。

これは公表文内の矛盾ではない。平文転送だけでも通信中の内容は読まれ、なりすましだけでも Node ID を知っていれば直接 fetch されうる。経路上の攻撃者が平文通信から Node ID を知ると、二つの欠陥を組み合わせて後からリポジトリ全体を取得できる、という関係である。

seeding を止めても、消えるわけではない

止め方は公表文に載っている。

rad ls --private --all
rad block <RID>
rad node stop

rad unseed ではなく rad block が勧められている。unseed はリポジトリの seeding policy を外すだけで、ノードは既定の policy に落ちる。既定は block なので、既定設定のままなら unseed でも足りる。既定を allow に変えているノードは、unseed してもそのリポジトリを提供し続ける。block は明示的な block を置き、ノードはそれを先に見る。

これで達成できないことが三つある。ローカルのコピーは消えない。$(rad path)/storage/ 以下の、rad: を外した RID の directory に残り、そこを削除するのはリポジトリと自分が持つすべての fork を手放す意味になる。迷うなら storage からは消さない。すでに fetch を済ませた authorized peer のコピーにも届かない。相手のノードも同じ欠陥を抱えているので、同じリポジトリを block するよう頼むことになる。そして過去の露出は取り消せない。

ネットワーク越しに他ノードへ送信した private リポジトリは、すべて漏洩したものとして扱う。暗号化されていない credential、鍵、token が含まれていたらローテーションする。storage に残しておけば、修正版が出てから seeding を再開できる。

Tor、I2P、その他の overlay network や VPN では足りない。これらは経路上の攻撃者からトラフィックを隠すので攻撃面は狭まるが、peer impersonation は防げず、標的を定めた洗練された攻撃では private リポジトリの内容が抜かれうる。

修正はメジャーバージョンを上げる

version negotiation の機能がなく、修正がワイヤ上で非互換になるため、後方互換の緩和策は作れない。だから修正リリースは breaking になり、メジャーバージョン番号が上がる。作業は進行中とされるが、時期は公表文に書かれていない。

解決の中身は、現行の Noise を使った独自プロトコルを iroh に置き換えることだ。iroh はオープンな標準の上に作られた peer-to-peer ネットワークスタックで、移行計画は以前から共有されていた。トランスポートの入れ替えは性質上後方互換にならず、ネットワークは upgrade 済みのクラスタと未 upgrade のクラスタに分断され、両者は通信できない。破壊をネットワーク側に寄せて storage layout の互換は保つ方針が示されており、NAT traversal のような機能も加わる。

自分のノードが private リポジトリを扱っていないなら、この件で今日変える設定はない。扱っているなら、判断は修正版を待つかどうかではなく、すでに同期したものをどこまで漏洩として処理するかになる。

出典 種別について