Electrum: 悪意のあるサーバーが、送信されたばかりのトランザクションを置き換え、ユーザーをRBF(Replace By Fee)を利用させようとする可能性がある。

### 概要

Electrumクライアントが接続する主要なサーバーは、トランザクションプール(「未承認」)内のトランザクションを信頼するものと見なされます。これは、設計ドキュメントに記載されています。[設計](https://electrum.readthedocs.io/en/latest/faq.html#does-electrum-trust-servers)。[0]

しかし、この仕組みを悪用する方法が発見されました。
- クライアントが新しいトランザクション(tx1)を送信すると、悪意のあるサーバーがそれを傍受し、
- クライアントの履歴を、攻撃者のアドレスにアウトプットが置き換えられた、競合する(無効な)トランザクション(tx2)で更新します。
- tx2には無効な署名が含まれていますが、これはライトクライアントの設計上、チェックされません。
- ウォレットは、tx2を未承認のトランザクションとして表示します。tx1は表示されません。
- クライアントが手動でtx2の手数料を上げると(RBF)、クライアントはより高い手数料で署名を行い、結果として攻撃者に手数料を支払うことになります。

### 修正

コミット90fe30822には、この問題を修正するコードが含まれており、バージョン4.8.3に含まれています。[1]
クライアントは、トランザクションプール内のトランザクションの`wallet.is_mine`入力の署名を検証するようになりました(ローカルの履歴に追加する前に)。

ユーザーは、バージョンアップを行うべきです(そして、通常は定期的にバージョンアップを行うべきです)。
回避策として、バージョンアップを行わない場合、手数料を上げる場合でも、トランザクションに署名する際に、アウトプットのアドレスと金額が期待どおりであることを確認する必要があります。

信頼できるサーバー(例えば、自分で運用するサーバー)に接続しているクライアントは、この問題の影響を受けません。

### 備考

- 一部のサーバーが、実際にこの攻撃を実行していることが確認されています。
- Electrumは、この件に関するユーザーからの報告を2件受けました。ユーザー1は、tx1をブロードキャストした後、ウォレットの履歴に異なるトランザクションが含まれていることに気づきました。ユーザー2は、tx2の手数料を上げようとした結果、資金を失いました。
- ユーザー1は、tx1がビットコインのP2Pネットワークを通じて伝播されなかったため、サーバーがそれを保持していたと報告しました。
- 両ユーザーとも、攻撃者が使用した出力アドレスが、tx1の正規アドレスの最後の4文字と一致するように偽装されていたと報告しました。
- ユーザー2の報告に基づくと、サーバーは、ユーザーが手数料を上げることを期待して、手数料がゼロのtx2を作成しました。
- 修正が適用されても、依然として「is_mine」の入力(つまり、ウォレットが所有するアドレスからの支払い)のみが検証されます。例えば、「受信」トランザクションは検証されません。クライアントは、完全なコンセンサスエンジン/スクリプトインタープリタを搭載していません。しかし、それでも、非「is_mine」の入力を検証するには、未確認の親トランザクションを再帰的に検証し、マイニングされたトランザクションに到達する必要があります。マイニングされたトランザクションについては、すでにSPV(Simplified Payment Verification)で検証しています。

### タイムライン

- 2026年10月11日:ユーザー1から、非公開の報告がありましたが、手数料を上げる手法(bump_fee)は実現されていませんでした。
- 2026年10月18日:ユーザー2(Raju-K12)から、手数料を上げた後に資金を失ったという非公開の報告がありました。
- 2026年10月23日:バージョン4.8.3が作成され、修正が適用されました。
- 2026年10月24日:バージョン4.8.3のバイナリファイルがリリースされました。
- 2026年10月24日:公的な情報公開。

### 謝辞

Electrumは、この問題を特定し、責任を持って私たちに報告してくれたユーザー1とRaju-K12に感謝します。

影響を受けるパッケージ:
- pip (Python) electrum: 4.8.3より前のバージョンに影響があります。4.8.3で修正されました。