You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The HatsSignerGate.sol::_countValidSignatures to check signatures validity uses ecrecover function that is subject to cross-chain replay attack.
function _countValidSignatures(bytes32dataHash, bytesmemorysignatures, uint256sigCount)
internalviewreturns (uint256validSigCount)
{
// There cannot be an owner with address 0.address currentOwner;
uint8 v;
bytes32 r;
bytes32 s;
uint256 i;
for (i; i < sigCount; ++i) {
(v, r, s) =signatureSplit(signatures, i);
if (v ==0) {
// If v is 0 then it is a contract signature// When handling contract signatures the address of the contract is encoded into r
currentOwner =address(uint160(uint256(r)));
} elseif (v ==1) {
// If v is 1 then it is an approved hash// When handling approved hashes the address of the approver is encoded into r
currentOwner =address(uint160(uint256(r)));
} elseif (v >30) {
// If v > 30 then default va (27,28) has been adjusted for eth_sign flow// To support eth_sign and similar we adjust v and hash the messageHash with the Ethereum message prefix before// applying ecrecover
currentOwner =ecrecover(keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", dataHash)), v -4, r, s);
} else {
// Default is the ecrecover flow with the provided data hash// Use ecrecover with the messageHash for EOA signatures
@> currentOwner =ecrecover(dataHash, v, r, s);
}
if (isValidSigner(currentOwner)) {
// shouldn't overflow given reasonable sigCountunchecked {
++validSigCount;
}
}
}
}
Internal pre-conditions
Safe.sol, HatsSignerGate.sol deployed on two blockchains so that: Safe.nonce() chain A > Safe.nonce() chain B and the signatures have been already used in a transaction in chain A
External pre-conditions
An attacker that takes signatures through the block explorer and use them in another chain (aforementioned chain B) when the Safe.nonce() value will be equal to the one used in chain A
Attack Path
The attacker could get from a block explorer the signatures used on one chain and replay them on another chain that has a lower nonce value when it will be equal to the nonce used in the OG transaction (first chain).
Impact
Permissions to execute a transaction coming from the Safe contract can be bypassed replaying signatures already used in another transaction on a different chain when the Safe.nonce() values are the same.
PoC
No response
Mitigation
Use ECDSA library functions
The text was updated successfully, but these errors were encountered:
Flat Watermelon Terrier
High
Cross-chain replay attack vulnerability
Summary
Signatures
needed to execute a transaction can be reused on another chain if several conditions are satisfiedRoot Cause
https://github.com/sherlock-audit/2024-11-hats-protocol/blob/main/hats-zodiac/src/HatsSignerGate.sol#L644-L684
The
HatsSignerGate.sol::_countValidSignatures
to checksignatures
validity usesecrecover
function that is subject to cross-chain replay attack.Internal pre-conditions
Safe.sol, HatsSignerGate.sol
deployed on two blockchains so that:Safe.nonce() chain A > Safe.nonce() chain B
and thesignatures
have been already used in a transaction in chain AExternal pre-conditions
An attacker that takes signatures through the block explorer and use them in another chain (aforementioned chain B) when the
Safe.nonce()
value will be equal to the one used in chain AAttack Path
The attacker could get from a block explorer the signatures used on one chain and replay them on another chain that has a lower
nonce
value when it will be equal to thenonce
used in the OG transaction (first chain).Impact
Permissions to execute a transaction coming from the
Safe
contract can be bypassed replayingsignatures
already used in another transaction on a different chain when theSafe.nonce()
values are the same.PoC
No response
Mitigation
Use ECDSA library functions
The text was updated successfully, but these errors were encountered: