Skip to content

Bug Bounty Submission: Same-Nonce Message Replay Vulnerability in Bridged Reputation Root Hash Update #1325

Description

@loopghost

Bug Bounty Submission: Same-Nonce Message Replay Vulnerability in Bridged Reputation Root Hash Update

Prerequisite

I ensured that this issue, specifically the weak nonce check (>=) in setReputationRootHashFromBridge allowing same-nonce replays, has not already been reported.

Summary

The setReputationRootHashFromBridge function within the ColonyNetworkMining.sol contract utilizes a non-strict nonce check (require(_nonce >= bridgeCurrentRootHashNonces[...])) for processing reputation root hash updates received via the bridge. This implementation flaw allows a message with a specific nonce to be processed multiple times consecutively if it is resubmitted before a message with a strictly higher nonce is processed. This enables a replay attack that forces the contract to re-execute logic, consume gas unnecessarily, and emit duplicate events, violating the integrity of the nonce mechanism and potentially impacting dependent off-chain systems. This constitutes a High Risk vulnerability according to the OWASP Risk Rating methodology.

Steps to Reproduce (Conceptual PoC)

This Proof of Concept demonstrates how a message with the same nonce can be processed multiple times. Let Chain M be the source chain and Chain C be the target chain where this code runs.

  • Initial State: Chain C has processed messages from Chain M up to nonce N. The state variable bridgeCurrentRootHashNonces[<Chain_M_ID>] on Chain C holds N. The reputation state is (HASH_OLD, LEAVES_OLD).

  • Valid Message Sent: Chain M sends Msg1 = (HASH_A, LEAVES_A, nonce=N+1) via the bridge to Chain C.

  • First Successful Processing on Chain C:

    • WormholeBridgeForColony calls ColonyNetworkMining.setReputationRootHashFromBridge(HASH_A, LEAVES_A, N+1).
    • Check: require(N+1 >= N) passes.
    • State updated to (HASH_A, LEAVES_A). Nonce map updated to N+1. Event ReputationRootHashSet(HASH_A, ...) emitted.
  • Replay Attempt: Before a message with nonce N+2 is sent/processed, an attacker resubmits the exact same Msg1 (containing nonce=N+1) to Chain C.

  • Second (Replay) Processing on Chain C:

    • WormholeBridgeForColony calls ColonyNetworkMining.setReputationRootHashFromBridge(HASH_A, LEAVES_A, N+1) again.
    • Check: require(nonce (N+1) >= bridgeCurrentRootHashNonces[<Chain_M_ID>] (N+1)) passes due to >=. <- Vulnerability.
    • State (HASH_A, LEAVES_A) is reapplied (no change). Nonce map set to N+1 (no change). Event ReputationRootHashSet(HASH_A, ...) is emitted again. Gas is consumed.

Expected Behavior

The nonce mechanism should strictly prevent the same message (identified by its nonce and origin) from being processed more than once. A check like require(_nonce > bridgeCurrentRootHashNonces[...]) should be used to ensure each nonce is processed at most once, rejecting replays of the exact same nonce.

Current Behaviour

The use of >= in the nonce check allows a message with nonce N+1 to be successfully processed even if the current stored nonce is already N+1, permitting consecutive replays.

Possible Solution

Modify the nonce check in ColonyNetworkMining.setReputationRootHashFromBridge to require the incoming nonce to be strictly greater than the last processed nonce:

// Inside setReputationRootHashFromBridge function
// Note: Assuming the map key is correctly representing the source chain ID in the actual implementation.
uint256 sourceChainId = ...; // Determine source chain ID correctly
uint256 lastProcessedNonce = bridgeCurrentRootHashNonces[sourceChainId];
require(_nonce > lastProcessedNonce, "colony-mining-bridge-nonce-must-be-greater");
bridgeCurrentRootHashNonces[sourceChainId] = _nonce;

Context

  • OWASP Risk Rating:

    • Likelihood: High. The flawed >= logic is present. Exploitation requires resubmitting a VAA, which is a feasible scenario for relayers or bridge mechanisms.
    • Impact: Medium. The replay does not corrupt the core state values but:
      • Weakens Nonce Integrity: Allows processing the same logical update multiple times.
      • Causes Unnecessary Gas Expenditure: Enables potential gas griefing on the target chain.
      • Generates Duplicate Events: Can disrupt off-chain indexers or systems relying on unique events per state update.
    • Overall OWASP Risk: High (Likelihood) * Medium (Impact) = High Risk.
  • Severity Classification: Based strictly on the OWASP Risk Rating methodology, a High Risk corresponds to a High Severity classification for this vulnerability.

Environment

  • Operating System: N/A (Blockchain/Solidity bug)
  • Ethereum client: N/A (Applies to any EVM chain where deployed)
  • solc version: 0.8.28 (as specified in pragmas)

Please consider rewarding this submission to your Bug Bounty Program accordingly as a High Severity vulnerability. Kindly issue the bounty to the following address: 0x36c81e0ec22cac063a0588b6165ce3fd022ab5b0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions