Valid signatures can be used to claim other incentives
Summary
Valid signatures can be used in order to claim any other incentive from the boost
Root Cause
In Boost protocol, there are two main components: Actions and Incentives. Boost owners creates actions and incentives and users complete these actions and they can claim their reward from incentives. Boost owners use trusted signer addresses in order to avoid violations.
In SignerValidator.sol signature is checked valid or not in validate() function.
function validate(uint256 boostId, uint256 incentiveId, address claimant, bytes calldata claimData)
external
override
returns (bool)
{
if (msg.sender != _validatorCaller) revert BoostError.Unauthorized();
(BoostClaimData memory claim) = abi.decode(claimData, (BoostClaimData));
(SignerValidatorInputParams memory validatorData) =
abi.decode(claim.validatorData, (SignerValidatorInputParams));
&> bytes32 hash = hashSignerData(boostId, validatorData.incentiveQuantity, claimant, claim.incentiveData);
if (uint256(validatorData.incentiveQuantity) <= incentiveId) {
revert BoostError.InvalidIncentive(validatorData.incentiveQuantity, incentiveId);
}
if (!signers[validatorData.signer]) revert BoostError.Unauthorized();
// Mark the incentive as claimed to prevent replays
// checks internally if the incentive has already been claimed
_used.setOrThrow(hash, incentiveId);
// Return the result of the signature check
// no need for a sig prefix since it's encoded by the EIP712 lib
return validatorData.signer.isValidSignatureNow(hash, validatorData.signature);
}
While creation of hash variable validatorData.incentiveQuantity variable is used but it's equal to total number of incentives in the boost. It normally should hash incentiveId in this function in order to create non-replayable hash. incentiveId usage in hashing is crucial in here because users can claim any incentive in the boost after claiming only one of them. incentiveData also doesn't hold the incentiveId data, it stores claimable reward amount of incentive.
Internal pre-conditions
User should complete at least 1 action and then he/she should be eligible for claiming at least 1 incentive
Attack Path
In a boost which has 3 actions and 3 different incentives, user should complete an action in order to claim one of the incentive.
Alice complete one of those action and get a signature from a trusted signer in order to claim her incentive.
This signature is not created especially for that incentiveId because of wrong hashing.
Now Alice can claim every incentive in the Boost using this signature.
Impact
High - Main invariant violation, users can claim any incentive just after claiming one of them.
Mitigation
In order to create a correct hash in order to claim an incentive. Adding incentiveId to hash is crucial for this kind of replay attack vectors.
TessKimy
High
Valid signatures can be used to claim other incentives
Summary
Valid signatures can be used in order to claim any other incentive from the boost
Root Cause
In Boost protocol, there are two main components: Actions and Incentives. Boost owners creates actions and incentives and users complete these actions and they can claim their reward from incentives. Boost owners use trusted signer addresses in order to avoid violations.
In SignerValidator.sol signature is checked valid or not in
validate()
function.While creation of hash variable
validatorData.incentiveQuantity
variable is used but it's equal to total number of incentives in the boost. It normally should hashincentiveId
in this function in order to create non-replayable hash.incentiveId
usage in hashing is crucial in here because users can claim any incentive in the boost after claiming only one of them.incentiveData
also doesn't hold the incentiveId data, it stores claimable reward amount of incentive.Internal pre-conditions
Attack Path
Impact
High - Main invariant violation, users can claim any incentive just after claiming one of them.
Mitigation
In order to create a correct hash in order to claim an incentive. Adding
incentiveId
to hash is crucial for this kind of replay attack vectors.