最近、過去(2021年)のLND実装のサービス拒否の脆弱性が公開されてたので見てみる↓
Denial-of-service bugs in LND's channel update gossip handling - Implementation - Delving Bitcoin
(最近は、Delving Bitcoinフォーラムでの議論も増えてるっぽい。)
2つともchannel_update
メッセージのハンドリングに起因する脆弱性。
メモリ不足によるクラッシュ
新しくチャネルを開設するとノードは以下のメッセージをネットワークにブロードキャストする。
channel_announcement
:
新しいチャネルをネットワークに通知するために利用。チェーン上でチャネルを一意に識別する情報(ショートチャネルID)や、両ノードの公開鍵、ファンディングアウトプットのマルチシグの鍵、各鍵に対する署名などが含まれる。channel_update
:
主に、ルーティング手数料やタイムロックの期待値を更新するために利用。
channel_update
は、チャネルの各方向毎に1つずつ作成されるので、合計3つのメッセージがブロードキャストされる。channel_update
にも、そのメッセージがチャネル参加者によって作成されたものであることを検証できるようにするため、ノードの公開鍵に対して有効なデジタル署名が付与されている。
ここで、これらメッセージを受け取るピアにおいては、必ずしもchannel_announcement
-> channel_update
の順にメッセージが届く保証はない。そのため、channel_update
の方が先に届いた場合、このメッセージが正しいか検証するためのノードの公開鍵はchannel_announcement
メッセージに含まれているため、channel_announcement
が届くまで検証が行えない。
この状況に対処するため、LNDではそのようなchannel_update
を一時的にメモリのバッファに保持するようなっていた。ただ、このバッファにはサイズ制限がなく、攻撃者が無効なchannel_update
を大量に送りつけてバッファを埋めることで、メモリ不足に陥らせるという攻撃が可能だった。
この脆弱性は、バッファーを上限付きのキャッシュに置き換えるようにする形で、LND v0.14.0で修正されている。
レート制限による検閲
チャネルの手数料やタイムロックの値を変更する場合、ノードはchannel_update
メッセージをブロードキャストする。このメッセージの作成にかかるコストは、せいぜい署名の生成くらいなので、何もしなければこのメッセージを大量に送りつけるスパムが可能になる。
そのため、各ライトニング実装では、このようなスパムを防ぐために、所定の時間内にリレーするchannel_update
の数をレート制限するようになっている。
LNDでは、このレート制限を行った後で、channel_update
メッセージの署名を検証していた。そのため、攻撃者は無効なchannel_update
メッセージを作成/送信し、無効なメッセージでレート制限されるようにし、他のチャネルの有効なchannel_update
の伝播が無視されるような攻撃をすることが可能になる。
この脆弱性は、レート制限の適用の前に署名検証が確実に行われるようにするようv0.15.0で修正された。