bitcoinjs-libに脆弱性、偽の取引一覧を受理 修正版あり
bitcoinjs-libのブロック検証が、取引を水増しした偽の一覧を正規のブロックとして受け入れる脆弱性があり、エクスプローラーや取引所の集計基盤が関係します。使っていれば、5.2.1・6.1.8・7.0.2のいずれかへ更新してください。
急ぎ度: 早めに
CVSS v4が9.3の深刻度で、認証なしにネットワーク経由で狙える一方、影響はブロック検証の機能を使う利用者に限られ、修正版は公開済みです。
関係があるか
bitcoinjs-libでブロックのMerkleルートを検証し、その結果を信頼して処理している組織が対象です。ブロックエクスプローラー、取引所のインデクサー、SPVクライアントが例に挙がっています。
| 製品 | 影響を受ける版 | 修正版 |
|---|---|---|
| bitcoinjs-lib 5系 | 2.3.0以上、5.2.1未満 | 5.2.1 |
| bitcoinjs-lib 6系 | 6.1.8未満 | 6.1.8 |
| bitcoinjs-lib 7系 | 7.0.2未満 | 7.0.2 |
確かめ方
- 1プロジェクトで
npm ls bitcoinjs-libを実行し、直接の依存だけでなく、他のパッケージ経由で入っている版も洗い出します。 - 2自社のコードで
checkTxRoots、Block.checkMerkleRoot、Block.calculateMerkleRootを呼んでいる箇所を検索し、検証結果をそのまま信頼していないか確認します。 - 3ブラウザー向けにバンドルして配布している場合は、配布物に含まれる版も確認します。
何が起きたか
bitcoinjs-libのブロック検証に、取引一覧を水増ししても正しいブロックとして通してしまう脆弱性が見つかりました。2026年11月4日に公表され、修正版が同時に出ています。
Merkleツリーの段の要素数が奇数のとき、このライブラリは最後の要素を自分自身とハッシュして段をそろえます。ところが fastMerkleRoot は、隣り合う同一のハッシュが並んでいても、それを呼び出し側に伝えません。
2.3.0で Block.checkMerkleRoot() と Block.calculateMerkleRoot() が入って以来この状態で、新しい版の checkTxRoots() や __checkMerkleRoot を通る検証も、再計算したルートが一致すれば改変の有無を調べずに受け入れます。
攻撃の流れ
-
1
細工したブロック
ピアが、同じ取引を重ねて追加した取引一覧のブロックを送ってきます。
-
2
ルートが一致
取引一覧は違っても、Merkleルート・ヘッダー・proof of work・ブロックIDは元のブロックと同じままです。
-
3
検証をすり抜け
bitcoinjs-libの検証が改変を検出せず、一覧を正当なものとして受け入れます。
-
4
処理側が誤作動
重複した取引を二重に処理したり、同じブロックハッシュを拒否リストに入れて正規のブロックまで拒否したりします。
どう悪用されるか
認証は不要で、ネットワーク越しにピアとしてブロックを送れる位置にいれば条件を満たします。利用者の操作も要りません。攻撃の複雑さは低いと評価されています。
被害が出るのは、ライブラリの検証結果を信頼して後続の処理を進める側です。重複した取引が二重に処理されると、エクスプローラーの表示や取引所の入出金集計がずれます。同じブロックハッシュを拒否リストに入れる実装では、正規のブロックまで拒否されます。
CVSS v4の評価では、データの完全性への影響が高く、連携する下流のシステムへの影響も大きいとされています。ブロックそのものの偽造ではなく、検証が見逃すことで下流が誤作動する点が、この脆弱性の性質です。
今すぐやること
-
1
使用箇所と版を洗い出す
直接の依存と間接の依存の両方で、bitcoinjs-libの版を確認します。ブロック検証の関数を呼んでいるサービスを特定し、本番のインデクサーや集計基盤を優先します。
npm ls bitcoinjs-lib -
2
修正版に更新する
5系は5.2.1、6系は6.1.8、7系は7.0.2に更新します。更新後はロックファイルとバンドルし直した配布物の版も確かめ、ブロック検証まわりのテストを回します。
-
3
処理済みデータを点検する
公表前から該当版を動かしていた場合は、同じ取引が重複して記録されていないか、同じブロックハッシュが拒否リストに入っていないかを調べます。入金の反映など金銭に関わる処理があれば、そこから確認してください。
-
4
ベンダーの告知を確認する
bitcoinjs-libのセキュリティアドバイザリで、影響範囲や補足情報を確認します。依存元のライブラリが版を固定している場合は、その提供元の対応状況も確認します。
すぐ更新できないとき
すぐに更新できない間は、取引一覧の中に隣り合う同一ハッシュがないかを自前で検査し、見つかったブロックは受理しない処理を入れます。検証に失敗したブロックを、ハッシュだけで恒久的に拒否リストへ入れない運用も有効です。いずれも更新までのつなぎで、根本の対処は修正版への更新です。
背景
bitcoinjs-libは、Node.jsとブラウザーで動くBitcoin向けのJavaScriptライブラリです。取引の組み立てや署名に使われるほか、ブロックの構造を読み、Merkleルートを再計算して検証する機能も持っています。そのため、ウォレットだけでなく、ブロックを読み込んで表示するエクスプローラーや、入出金を集計する取引所の基盤にも組み込まれます。
今回の問題の元は、奇数段で最後の要素を自分自身とハッシュするMerkleツリーの設計にあります。この設計では、取引を重ねて追加しても同じルートになる組み合わせができます。Bitcoin本体でも、この仕組みに由来する問題が2012年に報告されました。今回は、その検出がこのライブラリの検証経路に入っていなかったことが原因です。
よくある質問
Q.ウォレットや署名にしか使っていなければ、影響はありませんか。
Q.ブラウザー向けにバンドルして配布している場合は、どうすればよいですか。
この記事は、取得元の公開情報をもとに、人が監修しながらAIを活用して執筆しています。執筆と監修は佐々木 航が担い、公開したあとも人が内容を確認しています。誤りに気づいたときは直し、記事の末尾に訂正の行を残します。対応を決める前に、下の原文と参照先も確認してください。
原文の説明 取得元が公開している説明をそのまま載せています (多くは英語)。
bitcoinjs-lib is a JavaScript Bitcoin library for Node.js and browsers. From 2.3.0 until 5.2.1, 6.1.8, and 7.0.2, fastMerkleRoot pads odd Merkle-tree levels by hashing the final node with itself but does not report adjacent duplicate hashes. The affected block-root verifier was introduced as Block.checkMerkleRoot() alongside Block.calculateMerkleRoot(), while later versions expose validation through checkTxRoots() and __checkMerkleRoot; these validation paths can accept a recomputed root without checking for mutation. A peer can append duplicate transactions so a different transaction list retains the original Merkle root, block header, proof of work, and block identifier. Consumers that rely on block-root validation, including explorers, exchange indexers, or SPV clients, can process a duplicated transaction twice or blacklist the shared block hash and reject the honest block. This issue is fixed in versions 5.2.1, 6.1.8, and 7.0.2.
出典: CVE.org (CVE Program・cvelistV5) NVD