過去1週間(2026/09/07 - 2026/09/13)において、合計損失額が約3億2000万ドルに達する2件のセキュリティインシデントを確認しました。
| Date | Incident | Type | Estimated Loss |
|---|---|---|---|
| 2026/09/06 * | Liquid Network | Flawed Cache Key Construction | ~$320M |
| 2026/09/11 | Symbiosis | Flawed Off-Chain Deposit Validation | ~$770K |
*Liquid Networkのインシデントは9月6日に発生したものであり、前週のレポートには含まれていませんでした。完全性を保つため、本レポートに含めています。
Best Security Auditor for Web3
Validate design, code, and business logic before launch
今週の注目: Liquid Network
Liquid Networkのインシデントは、その巧妙なキャッシュキーの衝突メカニズムと、それによって引き起こされた甚大な損失により選定されました。検証データが以前のトランザクションのバイト列を異なる区切りで再分割するようなトランザクションを作成することで、攻撃者は一度も検証されていない証明に対してキャッシュされた検証結果が返されるようにしました。
2026/09/06、BitcoinのサイドチェーンであるLiquid Networkが攻撃を受け、約3億2000万ドルの被害が発生しました[1]。Liquidが稼働するノードソフトウェアであるElementsのrangeproof検証キャッシュにおける衝突により、あるアウトプットに対して記録されたvalidという判定結果が、まったく異なる第二のアウトプットに対して返されるという事態が発生し、その結果、後者の証明は一度も検査されることなく受理されました。攻撃者はこれを利用して、いかなるビットコインの裏付けもない4,000 L-BTCを生成し、その後、ネットワークの通常のペグアウト機能を通じてこれを引き出しました。翌日、3,400 BTCがフェデレーションに返却され、攻撃者の手元には約598.5 BTCが残りました[2]。
背景
Liquid Networkは、Bitcoinのコードベースから派生したオープンソースのブロックチェーンプラットフォームであるElementsを基盤として構築された、Bitcoinのサイドチェーンです。これは、メインチェーンでは実現できないほど高速、低コスト、かつプライベートにビットコインを移動させることを目的として存在しています。ビットコインは、双方向ペグを通じて2つのネットワーク間を移動します。ペグインでは、ユーザーがネットワークのフェデレーション(ペグ資金を共同で保管する、審査済み組織からなる固定グループ)にBTCをロックし、同額のL-BTCを受け取ります。ペグアウトでは、ユーザーがL-BTCを破棄し、フェデレーションが対応するBTCを解放します。Liquidのブロックはマイニングされません。フェデレーションのファンクショナリーノードのうち、ローテーションで選ばれた一部がブロックを提案し、フェデレーションの署名がしきい値に達すると、そのブロックが確定します。
Bitcoinと同様に、Liquidは資金をアカウントの残高としてではなく、未使用トランザクションアウトプット(UTXO)として追跡します。トランザクションは既存の未使用アウトプットを指定してロックを解除し、新しいアウトプットを作成しますが、作成される価値は消費される価値と等しくなければなりません。すべてのアウトプットにはロックスクリプトであるscriptPubKeyが付随します。スクリプトがOP_RETURNで始まるアウトプットは決して使用(spend)できません。これはデータを運ぶために存在し、ペグアウトはまさにこの種のアウトプットとして表現されます。
Liquidはまた、デフォルトで金額を秘匿します。アウトプットに数値を直接書き込む代わりに、その数値に対するPedersenコミットメントを書き込みます。コミットメントは加算的であるため、ノードは関係する値のいずれも知ることなく、トランザクションの入力と出力が均衡していることを確認できます。この性質には裏の側面もあります。コミットメントは負の値として振る舞う値を同様に秘匿できてしまうため、トランザクションのアウトプットがインプットを超えていても、それでも均衡が取れてしまう可能性があります。したがって、金額が秘匿されているすべてのアウトプットには、コミットされた金額が[0, 2^64)の範囲内にあることを証明するrangeproofが付随します。rangeproofの検証には高いコストがかかり、同じアウトプットが複数回検証されます(トランザクションがメンプールに入るときと、それがブロックに取り込まれるときの2回)。そのため、Elementsは、証明とそれが照合されたデータをキーとして、既に受理された証明のキャッシュを保持しています。
脆弱性の分析
不備は、Liquidのすべての参加者が実行するノードソフトウェアであるElementsが、既に検証済みのrangeproofをキャッシュする方法にあります。
CachingRangeProofChecker::VerifyRangeProof()は、目前のアウトプットに対してキャッシュエントリを導出し、ヒットした場合、証明に一切触れることなく即座に成功を返します。

このエントリはComputeEntryRangeProof()によって生成されます。この関数は4つのフィールドを1つのSHA-256ストリームに次々と書き込み、そのダイジェストを確定します。

4つのフィールドとは、rangeproof自体、金額に対するPedersenコミットメント、アウトプットが保持するアセットを識別するアセットジェネレーター、そして、受理された証明を特定のロックスクリプトに結び付けるために含まれるscriptPubKeyです。
これら4つのフィールドのいずれにも、長さプレフィックスや区切り文字が付いていません。rangeproofとscriptPubKeyの長さは可変であり、Pedersenコミットメントとアセットジェネレーターは常に33バイトのポイントです。したがって、ダイジェストは連結されたバイト列のみを記録し、あるフィールドがどこで終わり次のフィールドがどこから始まるかを示すものは何もありません。異なる4つのフィールドの組み合わせが偶然同じバイト列に連結される場合、同じエントリが生成され、先に検証された方が判定結果を残し、もう一方がそれを取得してしまいます。ハッシュ関数にはノードごとのランダムなソルトが加えられますが、そのソルトは両方のストリームに同様にプレフィックスとして付加されるため、ダイジェストを変化させるだけで2つの入力を区別することはできません。この不備は、コミット94000967で修正されました[3]。
攻撃の分析
以下の分析は、脆弱なコードを実行しているノードによって受理された、トランザクション271147...187ec5およびf24a4b...0a183fに基づいています。
- ステップ1: 攻撃者は、最初のアウトプットが67バイトのデータを運ぶ
OP_RETURNであるトランザクションを公開しました。
そのscriptPubKeyは6a 43(OP_RETURNオペコードに続く67バイトのプッシュ)、続いて2つの33バイトの値、そして末尾に6aを持ちます。プッシュされたこれら67バイトは、このトランザクションが必要とするデータではありません。それらは、まだ存在していないアウトプットの値コミットメントとアセットジェネレーターです。このアウトプットを検証したことにより、その4つのフィールド自身のエントリにvalidという判定結果が保存されました。
- ステップ2: 続いて攻撃者はインフレーショントランザクションを送信しました。このアウトプットの
OP_RETURNのscriptPubKeyは単一バイトの6aから構成され、その値コミットメントは、前のトランザクションのプッシュに埋め込まれた33バイトの値とまったく同一です。そのrangeproofフィールドは、前のトランザクションのrangeproof、コミットメント、アセットジェネレーターに続けて、2バイトの6a 43を付加して構築されました。

したがって、このアウトプットの4つのフィールドは、最初のトランザクションのものと同一のバイト列に連結されますが、異なる境界で再分割されています。
Primer: P0 │ C0 │ X │ S0, where S0 = 6a 43 <33-byte C1> <33-byte X> 6a
Inflation: P1 │ C1 │ X │ S1, where P1 = P0 ‖ C0 ‖ X ‖ 6a 43 and S1 = 6a
Both concatenate to: P0 ‖ C0 ‖ X ‖ 6a 43 ‖ C1 ‖ X ‖ 6a
キャッシュは以前の判定結果を返し、P1は一度も検証されませんでした。それはそもそもrangeproofではありません。C1は小さな負の金額へのコミットです。このトランザクションのもう一方のアウトプットは、攻撃者のアドレスex1q7kg...qa2wへの通常のpay-to-witness-public-key-hashアウトプットで、正当なrangeproofを伴う大きな正のコミットメントを持ち、両者が相殺し合うことで、トランザクションは均衡していました。これにより、いかなるビットコインの裏付けもない4,000 L-BTCの未使用アウトプットが残りました。
- ステップ3: 攻撃者はペグアウトを実行しました。2つのトランザクションが、通常の
OP_RETURNペグアウトアウトプットを通じて3,996.01834922および2.65138358のL-BTCをバーンし、合計3,998.66973280L-BTCとなりました。ペグアウトを承認するファンクショナリーノードは、同じ脆弱なコードでこれらを検証し、ビットコインを解放しました。3,995.99999857BTCと2.49749857BTCが、Bitcoin上で攻撃者に到達し、合計3,998.49749714BTCとなりました。
インシデントの解決作業中、ネットワークは一時停止し2つのチェーンに分岐しました[4]。その後、無効なペグアウトを拒否した状態で再開しました[2]。今日、ブロックエクスプローラーでは、リリースされたビットコインが既にフェデレーションのウォレットから流出していたにもかかわらず、primerトランザクションは確認済みとして表示され、インフレーショントランザクションは表示されません。翌日UTC 16:09:25に、攻撃者は3,400.00000000BTCをフェデレーションのペグウォレットに返却し、残りの約598.5 BTCは未返却のままとなっています[2]。両者は、Bitcoinトランザクションに埋め込まれたメッセージを通じて交渉を行いました[4]。
結論
攻撃者は暗号技術を破ることもなく、鍵を侵害することもありませんでした。不備は、rangeproofキャッシュが検証済みの対象をどのように識別していたかにありました。そのキーは、4つのフィールド(そのうち2つは可変長)を1つのハッシュストリームに連結しますが、各フィールドがどこで終わるかを示すものが何もありませんでした。そのため、第二のフィールドの組み合わせが同じバイト列を異なる形で再分割し、同じエントリに到達することが可能でした。保存されたvalidという判定結果が、いずれのノードも一度も検証していない証明に対して返され、rangeproofがその背後にある金額を制約しなくなった時点で、機密台帳はその秘匿された値を非負に保つ唯一の手段を失いました。1つの巧妙に作成されたアウトプットが4,000 L-BTCとなり、双方向ペグがそれをメインチェーン上のビットコインへと変換しました。
複数の可変長入力から導出される識別子は、それらの境界を確定させる必要があります。各フィールドに長さをプレフィックスするか、フィールドを別々の固定サイズのスロットにハッシュする方法によってです。それがなければ、導出は単射(injective)ではなくなり、2つの異なる入力が同一のものと誤認されうる可能性があります。この要件は、キャッシュがチェックの代わりを果たす場合において、最も厳しく求められます。なぜなら、そこではヒットすることが、そのチェックを実行しないという決定を意味するからです。
今週その他のインシデント
Symbiosis
2026/09/11、SymbiosisクロスチェーンブリッジのBitcoinルートが、BNB Smart Chain、Ethereum、Rootstockの各展開において攻撃を受け、流動性提供者およびユーザーに推定9.97 BTC(~$770K、9月11日時点の約77,000ドルのレートで算出)の損失を与えました[5]。Bitcoinデポジットからどれだけの合成ビットコインをミントするかを決定するオフチェーンコードが、預金者の身元を、預金者自身が制御できるトランザクションの一部分から取得していました。これにより、攻撃者は管理者として振る舞うことが可能となり、最小手数料をゼロ未満に押し下げました。その後、そのコードは符号を確認することなく、その手数料をデポジットから減算したため、減算が実際には加算として作用しました。
背景
Symbiosisは、資産そのものを転送するのではなく、ロックとミントによってチェーン間で価値を移動させるクロスチェーン流動性プロトコルです。スマートコントラクトを持つチェーンでは、ユーザーのトークンはソースチェーン上のPortalコントラクトによってロックされ、Synthesisコントラクトがホストチェーン上で合成トークン(sToken)を同額ミントします。sTokenをバーンすることで元の資産が解放されます[6]。このルートを通じてBitcoinが到達する形態はsyBTCであり、ビットコインの最小単位と一致する8桁の小数を持つトークンとして、BNB Smart Chain、Ethereum、Rootstock上で発行され、BTCB、cbBTC、WBTC、RBTCとペアを組んでプールを構成しています[5]。

Bitcoinにはそれらのいずれも存在しません。スマートコントラクトが存在しないため、デポジットをロックするPortalコントラクトもありません。その代わりに存在するのが、ポータル(同様の役割を果たす指定されたBitcoinアドレス)です。デポジットとは、そのアドレスに支払う通常のBitcoinトランザクションであり、送信先チェーンへの指示がデータとして付加されています。ブリッジに属するオフチェーンコードがそのデータを読み取り、誰がデポジットしているか、いくらか、合成トークンをどこに送るべきかを把握し、ポータルの手数料(ミントする金額が確定される前にデポジット金額から減算される)を適用します。この手数料の最小値は、管理者が設定するパラメーターです。
Bitcoin側の情報は送信先チェーンからは何も見えないため、Relayers Networkがその結果生成されたリクエストを運びます。このリクエストは、ブリッジのオンチェーンエントリポイントであるBridgeV2に、エンコードされた呼び出しとして到達し、Synthesisへと転送されます。認可はMPCキーに基づいています。プロトコルの署名者たちは単一の秘密鍵のシェアを保持し、リクエストに対して共同で1つの署名を生成します。中継されたリクエストのエントリポイントは、単一のモディファイアのみを持ち、呼び出しをディスパッチする前には他に何も行いません。

そのモディファイアは、リクエストをハッシュ化し、付随する署名がMPCアドレスに対して有効であることを要求します。

このコントラクトが確立しているのは、MPCキーがリクエストに署名したという事実です。リクエストが運ぶ金額自体は、Bitcoin側で計算されます。
脆弱性の分析
不備は送信先チェーンのコントラクトにはありません。それは、Bitcoinデポジットを読み取り、それらをクロスチェーンリクエストに変換するオフチェーンサービスにあります。そのソースコードは公開されていないため、以下の説明は、チームによる事後分析報告書[5]と、関連する可能性のあるコードスニペットを含む2024年のサードパーティ監査報告書[7]に基づいています。
デポジットのパスにある2つの欠陥が組み合わさる必要があり、事後分析報告書は、いずれか一方だけでは十分ではなかったと述べています。
第一の欠陥は、預金者がどのように識別されるかにあります。デポジットに付加された指示はデコードされ、それを行っている人物の身元を復元しますが、そのデコーダーは、この身元情報を、入力を使用(spend)する者が制御できるトランザクションデータの一部から取得していました。したがって、預金者は、ポータルが受け入れる最小手数料を設定する役割である管理者を含め、プロトコルが認識するいかなる当事者としても自分自身を名乗ることができました。
第二の欠陥は、その手数料が適用される方法にあります。2024年の監査は、デポジットアウトプットの値から手数料を減算することでミントする金額を計算するdecodeWrap()内の行を報告していました。
Value: types.Satoshi(tx.TxOut[idx].Value) - info.PortalFee,
その調査結果は、types.Satoshiは符号付き整数型であるにもかかわらず、PortalFeeを運ぶinfo構造体は信頼できず、ユーザーが制御可能であるため、結果が負の値に押し下げられ、送信先チェーン向けに符号なし値としてシリアライズされることで、任意の量の合成ビットコインをミントできるほど大きな値になり得るというものでした。この監査当時、この問題は修正済みとして記録されていました[7]。2026年の事後分析報告書は、同種の不備を記述しています。手数料は、その符号を確認することなくデポジットから減算されていました[5]。そのため、ゼロ未満の手数料は、デポジットを減少させるのではなく、増大させる結果となりました。デポジットパスの中には、ミントする金額を実際に受け取ったビットコインの範囲内に制限する仕組みが存在していなかったようです。
攻撃の分析
BNB Smart Chain、Ethereum、Rootstockを通じて、約4分間で12回の不正なミントが行われました[5]。以下の分析は、そのうちの1つである、BNB Smart Chain上のトランザクション0x9a2bc0...21b9b959に基づいています。

-
ステップ1: ポータルの管理者として振る舞い、攻撃者はポータルが受け入れる最小手数料をゼロ未満に移動させました。これにより、負の手数料を宣言したデポジットが拒否されるのではなく処理されるようになりました[5]。
-
ステップ2: 攻撃者は330サトシをデポジットしました。これは
0x000000000000014aとして表示されます。BNB Smart Chainに到達したリクエストは0x400000000000014aを運んでいました。これは、2^62のビットが設定された同じ値であり、4,611,686,018,427,388,234ベース単位に相当します。この2つの差はちょうど2^62であるため、このデポジットから減算された手数料は-4,611,686,018,427,387,904サトシでした。330 - (-4,611,686,018,427,387,904) = 4,611,686,018,427,388,234このリクエストはその形で署名され、中継されました。
-
ステップ3:
receiveRequestV2Signed()は、リクエストに対するMPC署名を検証し、それを転送し、metaMintSyntheticTokenBTC()に到達しました。この関数は、ソースチェーンIDに対応する実際のトークンの合成表現であるsyBTCを解決し、署名された全額に対してsynthesize()を呼び出しました。そのすべてが攻撃者のアドレス0x025122...5d3Ba2に転送されました。46,116,860,184.27388234 syBTCです。 -
ステップ4: 攻撃者は合成トークンをそれを保持しているプールに売却しました。Uniswap v4の
syBTC/WBTCプールを通じた単一のスワップにより、18,446,744,072,845,450,682ベース単位のsyBTC(上記のトランザクションでミントされた量のおよそ4倍)が決済され、4.38897292 WBTCが引き出されました。

さらに転送された結果、そのスワップの収益は約137 etherに達しました。
チームはBitcoinルートを一時停止し、約15.2 BTCのポータル資金が数時間以内に予備アドレスへ移動されました[5]。返却された金額の20%を報奨金として提供する提案が行われ、9月13日まで受付が開放されていました[8]。プロトコルの他のルートは影響を受けませんでした。
結論
鍵は盗まれず、コントラクトも意図されていないコードを実行するように欺かれたわけではありませんでした。送信先チェーンが検証した署名は正真正銘のものでした。それが認可していたのは、オフチェーンコードが既に2つの異なる形で誤って生成していた数値でした。1つは、預金者の身元を、預金者自身が制御できるフィールドから読み取ったことにより、攻撃者がポータルの管理者として振る舞い、その最小手数料をゼロ未満に押し下げることを可能にしてしまったことです。もう1つは、符号を確認することなくその手数料をデポジットから減算したことにより、負の手数料がデポジットを減少させるのではなく増大させてしまったことです。
信頼できない入力から読み取られた身元は、身元ではありません。特権的な役割は、預金者が自由に選べないもの、例えば実際に使用された入力を認可したアドレスをプロトコルが維持するリストと照合することによってのみ確立されるべきであり、預金者が自由に記入できるフィールドによってではありません。減算される値は両側に境界を必要とします。手数料はゼロとデポジット額の間に収まることが要求されるべきであり、ミントする金額は、ソースチェーンが実際に受け取った量を決して超えることが許されるべきではありません。どちらか一方の境界だけでも、この攻撃を単独で防ぐことができたでしょう。
参考文献
[1] https://x.com/Liquid_BTC/status/2096696272447218108
[2] https://x.com/Liquid_BTC/status/2097404704028545175
[3] https://github.com/ElementsProject/elements/commit/94000967f6dc05b1afd435e79b1bbc597e29f816
[4] https://www.coindesk.com/markets/2026/09/08/white-hat-hackers-return-most-of-usd320m-bitcoin-taken-from-liquid-network
[5] https://x.com/symbiosis_fi/status/2099566361940795831
[6] https://docs.symbiosis.finance/crosschain-liquidity-engine/synthesizing-process
[7] https://github.com/symbiosis-finance/audits/blob/master/Symbiosis%20Relayers%20Network/Symbiosis%20Relayers%20Network%202024%20-%20Decurity.pdf
[8] https://x.com/symbiosis_fi/status/2098442463358718264
BlockSecについて
BlockSecは、フルスタックのブロックチェーンセキュリティおよび暗号資産コンプライアンスのプロバイダーです。私たちは、プロトコルおよびプラットフォームのライフサイクル全体にわたり、コード監査(スマートコントラクト、ブロックチェーン、ウォレットを含む)の実施、リアルタイムでの攻撃の阻止、インシデントの分析、不正資金の追跡、AML/CFT義務の遵守を、お客様が実現できるよう支援する製品とサービスを構築しています。
BlockSecは、権威あるカンファレンスにおいて複数のブロックチェーンセキュリティ論文を発表し、DeFiアプリケーションに対する複数のゼロデイ攻撃を報告し、複数のハッキングをブロックして2000万ドル以上の資金を救出し、数十億ドル規模の暗号資産を保護してきました。
-
公式ウェブサイト: https://blocksec.com/
-
公式Twitterアカウント: https://twitter.com/BlockSecTeam



