Skip to content
#04 largest Input validation 2022

The BNB Chain Token Hub hack — $586M lost

Loss$586M
Date6 Oct 2022
ChainBNB Chain
Failure classInput validation
In assets2,000,000 BNB
Targetcross-chain bridge
1

What happened

The bridge verified withdrawals with an IAVL Merkle proof from the Cosmos library. The verifier confirmed that the proof's computed root matched the trusted root — but never confirmed that every leaf inside the proof was actually part of that computation. The attacker appended a forged leaf node that the hash walk simply never visited. Root matched. Payload was his. He minted himself 1,000,000 BNB, twice. The same flawed library sat under a large part of the Cosmos ecosystem.

2

How the attack ran

  1. Register as a relayerA legitimate, open bridge role
  2. Submit an IAVL range proofWith one extra leaf node appended to it
  3. The verifier hashes only what it walksThe forged leaf is never visited, so the root still matches
  4. Released twice1,000,000 BNB × 2 against a proof of nothing
3

The code

cosmos/iavl RangeProof — annotated, simplified from the real verifier
func (proof *RangeProof) Verify(root []byte) error {
    rootHash, err := proof.computeRootHash()   // walks only the nodes it needs
    if err != nil { return err }
    if !bytes.Equal(rootHash, root) {
        return ErrInvalidRoot
    }
    return nil
    // ❌ never asserts that every leaf in proof.Leaves was consumed
    //    by the walk — an extra, unvisited leaf changes nothing about
    //    the root hash, but the caller reads it as "proven".
}

// The forged proof:
  leaves = [ real_leaf , forged_leaf ]      // forged_leaf: "send 1,000,000 BNB to me"
  computeRootHash(leaves) == trusted_root   // ✅ passes
→ result: 2,000,000 BNB released against a proof of nothing
4

What would have caught it

What an audit looks for: proof verifiers must be complete, not just consistent. "The root matches" is a weaker statement than "this data, and only this data, produced the root." Any verifier that reads more input than it hashes is forgeable.
6

Sources

Every figure on this page comes from the post-mortems above, not from us. Losses are US dollars at the time of the incident.

Check your own contract for this

Input validation is one of the 203 classes the SaferICO scanner checks for. It will not review your signing process — but it will read your Solidity.

Run the scanner See how it is attacked Read the docs