Platform: Code4rena
Start Date: 01/08/2022
Pot Size: $50,000 USDC
Total HM: 26
Participants: 133
Period: 5 days
Judge: Jack the Pug
Total Solo HM: 6
Id: 151
League: ETH
Rank: 31/133
Findings: 2
Award: $246.32
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: berndartmueller
Also found by: 0xA5DF, arcoun, rotcivegaf, wastewa
When recoverKey
receive a messageSignatures with invalid length, the it's v != 27 && v != 28
or ecrecover
return a address(0)
, the call don't revert instead of that return the address(0)
As SignatureDecoder.sol
is a library, it will be used for several contracts, these could not take into account that an invalid signature does not revert but returns address(0) as signer
Basically, you can make an arbitrary signature with an arbitrary message, with address(0) as signer
Manual review
A solution it's use @openzeppelin-contracts/contracts/utils/cryptography/ECDSA.sol and use recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
of OZ to recover the key of each position
function recoverKey( bytes32 messageHash, bytes memory messageSignatures, uint256 pos ) internal pure returns (address) { if (messageSignatures.length % 65 != 0) { return (address(0)); } (uint8 v, bytes32 r, bytes32 s) = signatureSplit(messageSignatures, pos); ECDSA.recover(messageHash, v, r, s) }
#0 - 0xA5DF
2022-08-12T09:04:05Z
Warden is mentioning the underlying issue of #298 and #327 without actually demonstrating the impact.
#1 - jack-the-pug
2022-08-27T05:54:09Z
Duplicate of #327
🌟 Selected for report: Lambda
Also found by: 0x1f8b, 0x52, 0xA5DF, 0xNazgul, 0xNineDec, 0xSmartContract, 0xSolus, 0xf15ers, 0xkatana, 0xsolstars, 8olidity, Aymen0909, Bahurum, Bnke0x0, CertoraInc, Chom, CodingNameKiki, Deivitto, Dravee, ElKu, Extropy, Funen, GalloDaSballo, Guardian, IllIllI, JC, Jujic, MEP, Noah3o6, ReyAdmirado, Rohan16, Rolezn, Ruhum, Sm4rty, SooYa, Soosh, Throne6g, TomJ, Tomio, TrungOre, Waze, Yiko, _Adam, __141345__, a12jmx, ajtra, ak1, arcoun, asutorufos, ayeslick, benbaessler, berndartmueller, bin2chen, bobirichman, brgltd, bulej93, byndooa, c3phas, codexploder, cryptonue, cryptphi, defsec, delfin454000, dipp, djxploit, erictee, exd0tpy, fatherOfBlocks, gogo, hake, hansfriese, horsefacts, hyh, ignacio, indijanc, joestakey, kaden, mics, minhquanym, neumo, obront, oyc_109, p_crypt0, pfapostol, poirots, rbserver, robee, rokinot, rotcivegaf, sach1r0, saian, samruna, saneryee, scaraven, sikorico, simon135, sseefried, supernova
40.621 USDC - $40.62
recoverKey
function don't out of it's boundIn SignatureDecoder.sol, recoverKey
function if call this function with a high pos, this overflow the messageSignatures
, this would contain bytes (0) or maybe dirty bytes
Check if the position does not overflow the array:
function recoverKey( bytes32 messageHash, bytes memory messageSignatures, uint256 pos ) internal pure returns (address) { uint256 messageSignaturesLength = messageSignatures.length; if (messageSignaturesLength % 65 != 0) { return (address(0)); } if (pos < messageSignaturesLength / 65) { return (address(0)); } uint8 v; bytes32 r; bytes32 s; (v, r, s) = signatureSplit(messageSignatures, pos); // If the version is correct return the signer address if (v != 27 && v != 28) { return (address(0)); } else { // solium-disable-next-line arg-overflow return ecrecover(toEthSignedMessageHash(messageHash), v, r, s); } }