sherlock-audit / 2024-06-boost-aa-wallet-judging

3 stars 1 forks source link

0xloophole - Missing Cross-Chain Replay Protection in SignerValidator #436

Open sherlock-admin2 opened 2 months ago

sherlock-admin2 commented 2 months ago

0xloophole

Medium

Missing Cross-Chain Replay Protection in SignerValidator

Details

The SignerValidator contract aims to provide signature verification for the Boost protocol. However, the current implementation lacks explicit mechanisms to prevent signature replay attacks across different chains, potentially compromising the security of cross-chain interactions.

The SignerValidator contract primarily relies on a bitmask stored in the _used mapping to track claimed incentives and prevent replays. This approach, while effective within a single chain, does not inherently address the risk of replay attacks when a signature deemed valid on one chain could be re-submitted on a different chain.

https://github.com/sherlock-audit/2024-06-boost-aa-wallet/blob/main/boost-protocol/packages/evm/contracts/validators/SignerValidator.sol#L70

// Mark the incentive as claimed to prevent replays
// checks internally if the incentive has already been claimed
_used.setOrThrow(hash, incentiveId);

This code does not explicitly consider chain-specific information when tracking claimed incentives.

Impact

The absence of explicit cross-chain replay protection introduces a significant vulnerability. An attacker could replay a valid signature obtained on one chain to claim incentives fraudulently on a different chain, potentially leading to:

Double-Spending of Incentives: An attacker could claim the same incentive multiple times across different chains using a single signature. Depletion of Incentive Pools: Malicious actors could drain incentive pools on multiple chains by repeatedly replaying valid signatures. Loss of Funds: Users operating across multiple chains might unknowingly become victims of replay attacks, leading to a loss of assets.

Scenario

Consider a scenario where a user intends to participate in a Boost campaign running on two separate chains (e.g., Ethereum and Polygon). The user signs a message to claim an incentive on Ethereum. An attacker intercepts this signature and replays it on Polygon. Due to the lack of cross-chain replay protection, the attacker might succeed in claiming the incentive on Polygon using the user’s original signature.

Fix

To mitigate this, incorporate chain-specific information into the signature hashing or the claim tracking mechanism. One approach is to include the chain ID during signature generation and validation.

Example:

Modify the hashSignerData function to include the chain ID (block.chainid) in the hash calculation:

function hashSignerData(
    uint256 boostId,
    uint8 incentiveQuantity,
    address claimant,
    bytes memory incentiveData
) public view returns (bytes32 hashedSignerData) {
    return
        _hashTypedData(
            keccak256(
                abi.encode(
                    _SIGNER_VALIDATOR_TYPEHASH,
                    boostId,
                    incentiveQuantity,
                    claimant,
                    keccak256(incentiveData),
                    block.chainid // Include chain ID
                )
            )
        );
}

Additionally, modify the claim tracking mechanism within the IncentiveBits library to incorporate the chain ID, ensuring that each chain maintains its own independent record of claimed incentives.