LNの実装に影響を与える仕様レベルの脆弱性が公開されていたので内容を見てみよう↓
前提
まず、脆弱性の内容を理解するために、前提となる知識について。
dust limit
dust limitは、Bitcoinの1stレイヤーに組み込まれているポリシーで、この設定値を下回る量が設定されたアウトプットを持つトランザクションはリレーしないというもの。そのアウトプットを使用するために、そのアウトプットが持つ金額以上の手数料が必要になるような支払いは誰もしないよねと。そういうアウトプットをdustと呼んでいる。
dust limitはアウトプットのタイプによって異なり、その計算方法は、そのアウトプットのサイズと、そのアウトプットを使用する際に必要なインプットのサイズから以下のように算出される
(アウトプットのサイズ + インプットのサイズ) * dust relay fee / 1000
dust relay fee
はkBあたりのdustの定義値でデフォルト値は3000。このデフォルト値で計算した各アウトプットタイプのdustは以下のようになる↓
タイプ | アウトプットのサイズ | インプットのサイズ | dust |
---|---|---|---|
非Segwit | 34 | 148 | 546 |
P2WPKH | 31 | 67 | 294 |
P2WSH | 43 | 67 | 330 |
各タイプ毎にこれ未満の値がアウトプットに設定されているトランザクションはリレーされない。
この制限は、小額のUTXOを大量につくってBitcoinのUTXOセットを肥大化させフルノードの運用コストを上げるようなことを防止する目的で導入されている。
Lightningでのdust limitに関する処理
Lightningでもオフチェーン取引の際に作成されるコミットメントトランザクションについて、各アウトプットの量は↑のdust limit未満にならないようになっている。
まずチャネルを開設する際に、open_channel
/accept_channel
メッセージで互いにdust limitを通知するようになっており、この値はチャネルのライフタイム中は固定される。
そして、コミットメントトランザクションを作成する際は、交換したこのdust limitがそれぞれのコミットメントトランザクションに適用される。
つまり、以下の条件では、コミットメントトランザクションの該当するアウトプットが作成されない↓
to_local
のコインの量がdust limitより少ない場合、to_local
アウトプットは作成されない。to_remote
のコインの量がdust limitより少ない場合、to_remote
アウトプットは作成されない。- HTLCについては、
HTLCの額 - HTLC(success/timeout)の手数料
が、dust limitより少ない場合、そのHTLCのアウトプットは作成されない。
このように、dust limitを下回る額のアウトプットはコミットメントトランザクションでは表現されず(作成されず)、コミットメントトランザクションの手数料として扱われる。このようなアウトプットをトリムされたアウトプットと呼ぶ。
脆弱性の内容
BOLTの仕様では、↑のチャネル開設時に設定するdust limitの値は、チャネルリザーブ額未満であれば良いというルールしかない。これらの2つのパラメータは任意に設定できるため、各実装で許可されている最大値までdust limitを増やすことができる(LNDの場合チャネルキャパシティの20%まで、LDKの場合はキャパシティの100%までみたい)。
そのため、dust limitを大きめの値に設定すると、それ未満のHTLCはコミットメントトランザクションからトリミングされてしまう。また、コミットメントトランザクション内に処理中のHTLCが複数含まれる場合、全HTLCの総額に対してではなく各HTLC毎にこのdust limitチェックおよびトリミングがされる。なお、dustによるトリミングは、チャネルの開設者がコミットメントトランザクションの手数料を更新するためのfee_update
メッセージの配信によっても発生する可能性がある。
これを悪用すると、意図的に上限いっぱいのdust limitを設定し、保留中のHTLCがありそれがトリミングされている場合に、そのコミットメントトランザクションがブロードキャストされると、トリミングされたコインを手数料として焼却することができる。また、それがマイナーであれば、その分をマイニング手数料として入手することができるというのが、今回の脆弱性の内容。
このdustに関するHTLCの処理は以前から課題として挙がっており、2019年から議論、調査、緩和策の設計、実装が進められていた模様。
対応
上記の脆弱性に対して、提案されている緩和策が↓
- チャネル開設時にお互いに通知されたdust limit(
dust_limit_satoshis
)の値をチェックし、大きすぎる場合、チャネル開設を拒否するという修正(#894)。 - 新しい制限値
max_dust_htlc_exposure
を導入し、HTLCが発生が発生した際に、そのHTLCのコインの量 + コミットメントトランザクションのdust額の総計がこの制限値を超える場合、そのHTLCを失敗させるという修正(#919)
各ノードの対応状況
各ノードへのこの脆弱性のCVEと、パッチ適用バージョンは↓
- Eclair: v0.6.2+ (CVE-2021-41591)
- LND: v0.13.3+ (CVE-2021-41593)
- LDK: v0.0.102(Rust Lightningベースの開発キットで、まだプロダクション用のソフトウェアとしてはリリースされていない)
- c-lightning v0.10.2 (CVE-2021-41592)
現時点(2021/10/06)でパッチ適用済みのリリースがされてるのはLNDのみ(↑の2つの緩和策が実装されてる)っぽい。
アップデートせずにできる緩和策としては、現在開いているチャネルに大きな値のdust limitが設定されているか確認し、あればそのチャネルとのmin_htlc_msat
をそれ以上の額で更新すれば、トリミングされるHTLCはなくなる。