Develop with pleasure!

福岡でCloudとかBlockchainとか。

Dust limitを悪用したLightningプロトコルの脆弱性の開示

LNの実装に影響を与える仕様レベルの脆弱性が公開されていたので内容を見てみよう↓

[Lightning-dev] Full Disclosure: CVE-2021-41591/ CVE-2021-41592 / CVE-2021-41593 "Dust HTLC Exposure Considered Harmful"

前提

まず、脆弱性の内容を理解するために、前提となる知識について。

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はなくなる。