President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: medium
Valid

rankCandidatesBySig() is Replayable

Summary

rankCandidatesBySig() can be replayed. This allows a user to cast multiple votes (rankings) repeatedly on behalf of someone else.

Vulnerability Details

function rankCandidatesBySig(
address[] memory orderedCandidates,
bytes memory signature
) external {
bytes32 structHash = keccak256(abi.encode(TYPEHASH, orderedCandidates));
bytes32 hash = _hashTypedDataV4(structHash);
address signer = ECDSA.recover(hash, signature);
_rankCandidates(orderedCandidates, signer);
}

Impact

A user can vote repeatedly, thereby inflating the votes cast for their preferred candidates. The user may not even know that they cast illegitimate votes since someone else paid for the transaction on their behalf.:brThe result would be an unfair election that does not represent the population's will.

Tools Used

Manual Review

Recommendations

Implement a "isExecuted" mapping in RankedChoice.sol that keeps track of the signatures already executed. Then, implement a check in rankCandidatesBySig() before the call to _rankCandidates that ensures the signature has not already been executed. This prevents signed un-sent transactions from being replayed in rankCandidatesBySig().

Updates

Lead Judging Commences

inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Validated
Assigned finding tags:

Replay Attack - The same signature can be used over and over

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.