← Back to Hack Archive

Nomad Bridge Hack

August 1, 2022$190 millionInput Validation VulnerabilityMultiple

The Story

On August 1, 2022, the Nomad Bridge, a cross-chain communication protocol that allowed users to transfer tokens between different blockchains, suffered one of the most unusual hacks in DeFi history. Due to a critical validation error in a recent upgrade, the bridge essentially became a free-for-all where anyone could withdraw funds they didn't deposit.

What made this hack particularly unique was that it didn't require sophisticated programming knowledge. Once the initial exploit was discovered, hundreds of copycats joined in, resulting in approximately $190 million being drained from the protocol in what security researchers described as a "decentralized crowd-looting."

In the days following the hack, Nomad worked with white hat hackers and managed to recover about $36 million of the stolen funds. The team also created a recovery process for users affected by the exploit and implemented a redesigned architecture with improved security measures before relaunching.

Technical Analysis

The Nomad Bridge hack stemmed from an extraordinarily simple yet devastating initialization error in a recent upgrade. During a routine upgrade, the Nomad team initialized the trusted root with the value 0x00 instead of the intended valid merkle root. This seemingly small error had catastrophic consequences.

The vulnerability effectively allowed any message to be automatically proven valid:

// Simplified representation of the vulnerable function
function process(bytes memory message, bytes32[] memory proof) public {
    bytes32 committedRoot = committedRoots[msg.sender];
    
    // The fatal bug: committedRoot was initialized to 0x00
    // Any message could be proven valid because the check below
    // would always pass when using 0x00 as proof
    if (MerkleLib.verify(committedRoot, proof, keccak256(message))) {
        // Process message and transfer funds
        _processMessage(message);
    }
}

The simplicity of the exploit meant that:

  1. The initial attacker only needed to find a valid transaction on the bridge
  2. They could then copy this transaction but change the recipient address to their own
  3. Since the trusted root was 0x00, the transaction would be considered valid
  4. They could withdraw funds they never deposited

Once the vulnerability was discovered, hundreds of users with varying levels of technical knowledge began copying the exploit pattern, leading to the mass extraction of funds from the bridge.

Lessons Learned

  1. Initialization values are critical security parameters that should be carefully verified
  2. Changes to trusted roots and other security-critical values should require multi-signature approval
  3. Deploy contracts with fail-safe mechanisms that can pause operations when unusual activity is detected
  4. Implement rate limiting on withdrawals to prevent mass drainage even in case of vulnerabilities
  5. Formal verification should be applied to security-critical functions, especially after upgrades