Back to Blog

HarmonyのクロスシャードONEミント + 約4700万ドルの鍵漏洩による損失 | BlockSec

Code Auditing
August 19, 2026
8 min read
Key Insights
  • 今週は5件の注目すべきセキュリティインシデントが取り上げられており、定量化された損失は約4,700万ドルに及ぶ。そのうち3件は秘密鍵の漏洩によりユーザー資金が直接移動されたもの(Unknown Whale Wallet 約2,500万ドル、Kite 約1,400万ドル、Coinsbuy 約790万ドル)であり、一方、注目インシデントであるHarmonyはチェーン実装上の欠陥であり、その偽造されたONEには実現可能または確認済みの損失額が存在しない(表の注釈を参照)。

  • Harmonyの宛先シャードは、クロスシャードのレシートにおける「使用済み」マーカーを、署名済みのソースブロックヘッダーではなく、認証されていない証明フィールド(MerkleProof.ShardIDMerkleProof.BlockNum)から導出していた。そのため、攻撃者はこれらのフィールドのみを変更することで、既にクレジット済みのレシートをリプレイし、ソースシャード側で対応するデビットが発生しない状態でネイティブのONEをミントすることが可能であった。もう一つの、ステーキング導入前のクォーラム検証における欠陥は、実際に署名者ビットマップで有効化されたバリデーターの数ではなく、委員会全体の規模をカウントしていた。

  • チェーン実装は、既に消費された状態を識別するために使用するすべてのフィールドを認証しなければならず、また、委員会全体ではなく実際に署名を行ったバリデーターによってクォーラムを判断しなければならない。

先週(2026/08/10 - 2026/08/16)は、以下の5件の注目すべきセキュリティインシデントが発生し、合計損失額は約4,700万ドルに上りました。

日付 インシデント タイプ 推定損失額
2026/08/10 Coinsbuy 秘密鍵の漏洩 ~$7.9M
2026/08/10 不明なホエールウォレット 秘密鍵の漏洩 ~$25M
2026/08/12 Harmony バリデーション上の問題 不明*
2026/08/13 Kite 秘密鍵の漏洩 ~$14M
2026/08/15 Fox ビジネスロジックの欠陥 ~$117K

*Harmonyは、確認済みの第一波としてONEが40億トークンミントされたことと、より広範な再構築により約3.01兆ONEが偽造され、そのうち約2.385兆ONEが転送されたと報告しています[1]インシデント前の価格である約0.001183ドルで計算すると、偽造された金額の名目上の価値は約35.6億ドルに相当しますが、これはONEの総供給量の約200倍に達し、トークンの市場総額を大幅に超えているため、実現可能でも、実現した損失として確認されたものでもありません。Harmonyはその後、チェーンを攻撃前のチェックポイントまでロールバックし、偽造された状態を破棄しました[2]。したがって、Harmonyは総損失額から除外されています。

選定理由

  • Harmony: チェーン実装のリプレイ保護の欠陥により、Harmonyエコシステム全体で大規模な不正なネイティブトークンの発行が可能になったため選出されました。調査の過程で、ステーキング前のクォーラム検証における別の脆弱性が特定されましたが、この脆弱性が実際のエクスプロイトに関与したかどうかは確認されていません。

Best Security Auditor for Web3

Validate design, code, and business logic before launch

今週の注目: Harmony

今週Harmonyを取り上げるのは、この欠陥がアプリケーションコントラクトではなくチェーン実装そのものに存在していたためです。これは、レイヤー1全体の基盤資産を膨張させる可能性があるという点で、異例なほど影響度の高い失敗形態です。

2026年8月12日、シャーディング型のレイヤー1ブロックチェーンであるHarmonyは、クロスシャードレシートのリプレイの欠陥により、ネイティブトークンであるONEの不正なミントを被りました。宛先シャードは、ソースコミッティーの署名でカバーされていないフィールドを使用して、既に消費されたレシートを識別していたため、攻撃者はそれらのフィールドのみを変更することで、正当かつ以前にクレジットされたレシートを再提示し、ソースシャード側で対応するデビットが発生することなく、再度クレジットさせることができました。Harmonyは、確認済みの第一波としてONEが40億トークンミントされたことと、より広範な再構築により約3.01兆ONEが偽造され、偽造ミントウォレットにより約2.385兆ONEが転送されたこととの整合性を調整していました。これらのいずれも実現した損失として確認されたものではなく、最終的な影響はロールバックおよび取引所側の調整に左右される可能性があります[1][2]。調査の過程で、Harmonyはステーキング前のクォーラム検証における別の欠陥を特定しましたが、今回のエクスプロイトがこれに依拠していたかどうかは確認していません。

背景

Harmonyはシャーディング型のレイヤー1ブロックチェーンです。各シャードは独立した状態を維持しているため、ソースシャードは宛先シャード上のアカウントを直接変更することはできません。シャード間で価値を移動させるために、Harmonyは非同期のレシートベースの設計を採用しています。ソースシャードが送信者からデビットしてクロスシャードレシートを発行し、宛先シャードが後で受信者にクレジットするという仕組みです。

クロスシャードレシートは転送そのものを記録します:

type CXReceipt struct {
    TxHash    common.Hash
    From      common.Address
    To        *common.Address
    ShardID   uint32
    ToShardID uint32
    Amount    *big.Int
}

宛先シャードは、レシート単体を信頼するわけではありません。レシートはCXReceiptsProofの中を伝わり、それにはマークルプルーフ、ソースブロックのヘッダー、そのヘッダーに対するソースコミッティーのコミット署名が含まれています:

type CXMerkleProof struct {
    BlockNum      *big.Int
    BlockHash     common.Hash
    ShardID       uint32
    CXReceiptHash common.Hash
    ShardIDs      []uint32
    CXShardHashes []common.Hash
}

type CXReceiptsProof struct {
    Receipts     CXReceipts
    MerkleProof  *CXMerkleProof
    Header       *block.Header
    CommitSig    []byte
    CommitBitmap []byte
}

通常の検証パスでは、署名済みのソースヘッダーとそのコミッティー署名に対してプルーフを検証します:

VerifyIncomingReceipts()
  -> IsSpent()
  -> ValidateCXReceiptsProof()
      -> VerifyHeaderSignature()
          -> verifySignature()
              -> DecodeSigBitmap()
              -> IsQuorumAchievedByMask()
              -> aggSig.VerifyHash()

ソースシャードはデビットを一度だけ実行するため、宛先シャードは各クロスシャードレシートが一度だけ消費されることを保証しなければなりません。

脆弱性分析

クロスシャード決済パスには2つの問題が含まれていました。消費済みレシートの識別方法におけるリプレイ保護の弱点と、ステーキング前のクォーラム検証の弱点です。

クロスシャードレシートのリプレイ

リプレイ保護はレシートの「消費済み」マーカーを記録・検索していましたが、そのキーはマークルプルーフの2つの可変フィールドから生成されていました:

CXMerkleProof.ShardID
CXMerkleProof.BlockNum

Bloomハードフォークにより、2026年7月13日のエポック2964でメインネットでこの点が強化され、IsCXMerkleProofReplayFixEpochによってゲートされました[3]。署名済みのHeader.Epoch()がこのエポック以降であるプルーフについては、IsSpent()およびWriteCXReceiptsProofSpent()は、これら2つのフィールドではなく署名済みのソースヘッダー(Header.ShardIDおよびHeader.Number)から消費済みマーカーのキーを生成するようになりました。ただし、この強化されたキー生成方式が遡及的に適用されることはありませんでした。Header.Epoch()がフォーク以前であるプルーフについては、両関数とも従来のMerkleProof.ShardIDおよびMerkleProof.BlockNumへのフォールバックが維持されており、それらのエポックにおいてはValidateCXReceiptsProof()がこれらを署名済みヘッダーに結び付けることは一度もありませんでした。

これら2つのフィールドは、ソースのHeaderのみをカバーするコミット署名の対象外です。Headerを変更すればVerifyHeaderSignature()は失敗しますが、MerkleProof.ShardIDまたはMerkleProof.BlockNumを変更してもチェックは一切破られません。ヘッダー署名も、これらのエポックにおいてそれらをHeaderに結び付けることが一度もなかったプルーフ検証も、破られないのです。従来の消費済みマーカーのキーがこれらの未認証フィールドから生成されていたため、レシートのリプレイ保護上の識別情報は、プルーフの他の部分を認証する署名から切り離されていました。同じ署名済みヘッダーとレシートを持つが、MerkleProof.ShardIDまたはMerkleProof.BlockNumの値が異なる2つのプルーフは、消費済み追跡の目的上、別個のものとして扱われていたのです。

ステーキング前のクォーラムチェック

2つ目の欠陥は、ステーキング前のクォーラム検証に影響を与えました。uniformVerifier.IsQuorumAchievedByMask()のロジックは、しきい値を以下と比較していました

len(mask.Publics)

これを署名者の数として扱っていました。しかし、mask.Publicsはシャードおよびエポックのコミッティーの公開鍵の全リストであり、実際に署名したバリデーターの集合ではありません。実際に署名した集合は署名者ビットマップによって表現されています。その結果、空の署名者ビットマップであってもクォーラムしきい値をクリアできてしまう可能性がありました。なぜなら、このチェックが有効なビットマップのビット数ではなくコミッティーのサイズを測っていたためです。これに単位元(全ゼロ)の集約BLS署名を組み合わせることで、ステーキング前時代のソースヘッダーが十分なクォーラムを備えているように見せることが可能になり得ました。

攻撃分析

攻撃者は、ハードフォーク以前のソースシャードブロックからの、正当かつ既に処理済みのクロスシャードレシートから開始し、未認証のプルーフ識別情報のみを変更することでそれをリプレイしました。偽造されたONEは4つのエクスプロイター・ウォレットにミントされました。以下の分析はトランザクション0xf3d4e8b1...8242c7fおよび0x9a756ef9...b0a4d678に基づいています。

  • ステップ1: 攻撃者は、ハードフォーク以前のソースシャードブロックから有効な過去のCXReceiptsProofを取得しました。このプルーフには有効なレシート、有効なソースブロックヘッダー、有効なソースコミッティーのコミット署名が含まれていました。

  • ステップ2: 宛先シャードは既にこのレシートを一度消費し、マークルプルーフのフィールドから生成されたキーで消費済みマーカーを書き込んでいました。

  • ステップ3: 攻撃者は、未認証のプルーフ識別情報フィールドのみを変更し、署名済みヘッダーと署名でカバーされる全フィールドは手を加えないままにしました:

    MerkleProof.ShardID
    MerkleProof.BlockNum
  • ステップ4: 変更されたプルーフは、後の宛先シャードのブロックに着信レシートとして提出されました。IsSpent()は変更されたフィールドから消費済みマーカーのキーを生成したため、以前のマーカーを見つけることができず、レシートは未消費に見えました。

  • ステップ5: ValidateCXReceiptsProof()はそれでもこのプルーフを受け入れました。変更された識別情報フィールドは署名でカバーされていない一方で、認証対象の全フィールド(ヘッダーハッシュと発信レシートハッシュ、マークルプルーフのブロックハッシュとレシートハッシュ、レシートハッシュ、そしてコミット署名とビットマップ)は変更されないままだったためです。

  • ステップ6: ApplyIncomingReceipt()が宛先シャード上で実行され、db.AddBalance(*cx.To, cx.Amount)により受信者に再度クレジットされました。元のクロスシャードトランザクションは既に一度だけ実行済みであったため、ソースシャード上での対応するデビットは発生せず、宛先シャード上でネイティブONEの膨張が生じました。

結論

プロジェクトが確認した根本原因は、プロトコルレベルのリプレイ保護の失敗でした。クロスシャードレシートの消費状態を示す識別情報が、署名済みのソースヘッダーではなく未認証のプルーフフィールドから生成されていたため、既に処理済みのレシートが再度クレジットされ得たのです。Harmonyはまた、ステーキング前のクォーラム検証における別の欠陥を確認しましたが、公開されている情報からは、攻撃者が今回それを利用したかどうかは確認できません。

パッチは両方のギャップを解消しています[4][5][6]。より広く言えば、チェーン実装は既に消費された状態を識別するために使用するすべてのフィールドを認証しなければならず、クォーラムの判断は実際に署名したバリデーターに基づいて行うべきであり、コミッティー全体に基づくべきではありません。

Get Started with Phalcon Explorer

Dive into Transactions to Act Wisely

Try now for free

Get Started with Phalcon Security

Detect every threat, alert what matters, and block attacks.

Try now for free

参考文献

BlockSecについて

BlockSecは、フルスタックのブロックチェーンセキュリティおよび暗号資産コンプライアンスのプロバイダーです。当社は、プロトコルおよびプラットフォームのライフサイクル全体にわたって、コード監査(スマートコントラクト、ブロックチェーン、ウォレットを含む)の実施、攻撃のリアルタイムでの阻止、インシデントの分析、不正資金の追跡、AML/CFT義務の遵守を、お客様が実現できるよう支援する製品とサービスを構築しています。

BlockSecは、権威ある学会において複数のブロックチェーンセキュリティに関する論文を発表し、DeFiアプリケーションに対する複数のゼロデイ攻撃を報告し、2,000万ドル以上を救済するために複数のハッキングを阻止し、数十億ドル相当の暗号資産を保護してきました。

Sign up for the latest updates
約160万ドルの損失:MokeトークンとLpdFiへの攻撃 | BlockSec週次レポート
Security Insights

約160万ドルの損失:MokeトークンとLpdFiへの攻撃 | BlockSec週次レポート

2026年8月3〜9日の週、BNBチェーンで2件の重大なセキュリティインシデントが発生し、いずれも価格操作により総損失は約160万ドルに上った。LpdFi事件(約69.7万ドル)では、注文評価と利息償還の両方に同じ操作可能なPancakeSwapペアのリザーブが使用され、攻撃者がポジションの元本を水増しし過大な利息を請求した。Mokeトークン(約90.6万ドル)では、操作可能なスポット価格とLP配当の重複計上を組み合わせ、MOKEを水増し請求してBNB配当を複数回取得した。

COLDCARDの事件:ウォレットの「ランダム」シードがランダムではなかった時
Security Insights

COLDCARDの事件:ウォレットの「ランダム」シードがランダムではなかった時

COLDCARDファームウェアのビルド・統合バグにより、Bitcoin種生成がソフトウェアRNGフォールバックに誘導され、脆弱な乱数によりウォレットの秘密鍵がオフラインで復元可能となった。欠陥は種自体にあるためファームウェア更新では修正不可。2026年8月7日までに確認された被害は1,405 BTC(約91億円)、非公式推定では最大2,055 BTCに上る。

〜8800万ドルの損失:COLDCARDとLULAのエクスプロイト|BlockSec週次レポート
Security Insights

〜8800万ドルの損失:COLDCARDとLULAのエクスプロイト|BlockSec週次レポート

2026年7月27日〜8月2日、BitcoinとBNBチェーンで計約8800万ドルの損失をもたらす2件のインシデントが発生。COLDCARDではファームウェアのエントロピー障害により、RNG設定マクロの有効性ではなく存在のみを確認するビルドガードが決定論的なソフトウェアフォールバックへシード生成を誘導。攻撃者は少なくとも1,370 BTC(約8800万ドル)を窃取。BNBチェーンのLULAトークンでは、攻撃者が特権的な`recycle()`関数を呼び出し、PancakeSwap V2のペアからLULAを引き出して流動性を枯渇させ、約57.8万ドルの損失が発生。

Best Security Auditor for Web3

Validate design, code, and business logic before launch. Aligned with the highest industry security standards.

BlockSec Audit