Skip to content

[Security] relay read: 未証明の DHT 候補を member として扱い、credential 転送と認可否定の受理を行っている #63

Description

@somasekimoto

背景

PR #54 のディープレビュー指摘(blocker 1 / 3)。read relay 経路には、ネットワーク参加が自由(Byzantine 前提)であることと噛み合わない箇所が 3 つある。いずれも「DHT 近傍であること」を「正規 member であること」と同一視していることに起因する。

問題

1. 未証明の DHT 候補へ caller の credential を転送する

resolve_members(state_node_service.rs)はローカルに ContentNetwork レコードが無い場合、find_closest_peers の結果をそのまま member として扱う。その候補へ relay_read_content / relay_read_history が caller の token・request signature・timestamp を転送する。

XOR 距離は配置規則であって、そのピアが現在も正規 member であることの暗号学的証明ではない。攻撃者は自分の PeerID を対象コンテンツの DHT キー近傍に置くだけで候補に入れる。

現状の影響範囲(PR #56 の署名統一後): リクエスト署名は monas-request-v1:<op>:<resource>:<timestamp>:<body digest> に束縛されるようになったため、盗んだ署名を別 content や別 operation に転用することはできない。残るのは「同じ content の同じ操作を 5 分以内に再実行できる」ことと、委譲 JWT 自体が TTL 内で候補ノードの手に渡ることである。read relay では候補ノードはどのみち暗号文を扱う立場なので、追加で得られる情報は限定的だが、credential を未証明の相手に渡す構造そのものは解消されていない。

2. 最初に成功した応答をそのまま受理する

relay_read_data は最初に Ok を返した候補の (data, version) を返す。wire response 内の content_id を要求したものと照合していない。

PR #56 の CID 再計算により payload の改ざんは弾けるが、cross-content の取り違え(別 content の正規 Node を返す)は CID 検証だけでは弾けない — クライアントが要求した version CID と一致しなければ落ちるので実害は限定的だが、応答を要求へ束縛する検証は明示的に入れるべき。

3. 未証明ピアの 401/403 を権威ある最終判定として扱う

record_relay_read_error が auth verdict(AuthenticationFailed / AuthorizationFailed)を受け取ると ControlFlow::Break で failover を即座に打ち切る。「member が実際に評価した」という前提だが、その判定主体が正規 member である保証がない。

→ DHT 近傍を操作できる 1 台が、正当なユーザーの read を恒久的に拒否できる(可用性攻撃)。

あるべき修正

根本は「認証された member discovery」を持つこと:

  • member であることを検証可能にする(ContentNetwork レコードへの署名、または member 自身が提示できる membership proof)
  • 未証明の候補へは実 credential を渡さない。あるいは client が最終 member へ直接 proof を提示する構造にする
  • 応答を要求した content / series / version へ束縛して検証する
  • 単一候補の否定応答で failover を打ち切らない。または否定応答を「正規の policy holder による判定」と検証できるようにする

関連

テスト観点

  • 悪意ある DHT 候補が credential を再利用しようとするケース
  • cross-content response を返すケース
  • 偽 401/403 を返す候補が 1 台混じっても、正規 member から読めること

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions