President Elector

First Flight #24
Beginner FriendlyFoundry
100 EXP
View results
Submission Details
Severity: high
Invalid

rankCandidatesBySig function allows hacker to replace user signature

Summary

The rankCandidatesBySig() function in the RankedChoice contract allows voters to cast their ranked votes using an off-chain signature. However, the function does not verify whether the candidate rankings passed on-chain are the same as the ones signed off-chain by the voter. This opens up a vulnerability where an attacker can manipulate a legitimate voter's signed vote and pass different candidates to the contract.

Vulnerability Details

The key issue in the rankCandidatesBySig() function is the lack of validation between the candidate rankings signed off-chain by the voter and the rankings passed on-chain by the user submitting the vote. Specifically, the function uses the voter's signature to recover their address but does not compare the data being signed (the orderedCandidates array) with the actual array submitted to the contract.

Here’s how the vulnerability occurs:

  1. A legitimate voter signs an off-chain message containing their chosen candidate rankings (e.g., [candidate1, candidate2, candidate3]).

  2. An attacker intercepts the signature but modifies the candidate rankings (e.g., [attacker1, attacker2, attacker3]) when submitting the vote on-chain.

  3. The contract recovers the correct signer from the signature but does not verify that the rankings match what the signer intended to vote for.

Since the function does not check if the rankings submitted match the rankings that were signed, the attacker's manipulated candidate list is accepted.

Impact

This vulnerability allows an attacker to alter a legitimate voter’s ranked choice vote by changing the candidate list while using the voter’s valid signature. The effects of this include:

  • Vote Manipulation: The attacker can effectively control which candidates receive votes, leading to unfair election results.

  • Loss of Trust: Voters may lose confidence in the system if votes can be altered without detection, potentially compromising the integrity of the entire voting process.

Tools Used

ECDSA (Elliptic Curve Digital Signature Algorithm): This is used for recovering the voter's address from the signature. However, the vulnerability is due to not verifying the integrity of the signed message with the input data.

Recommendations

Validate Input Data: Modify the rankCandidatesBySig() function to compare the hash of the orderedCandidates array passed on-chain with the hash of the array that was signed off-chain.

  • Hash the orderedCandidates array using keccak256 and compare it with the hash that was signed by the voter.

  • Implement Integrity Check:

    bytes32 structHash = keccak256(abi.encode(TYPEHASH, orderedCandidates));
    bytes32 hash = _hashTypedDataV4(structHash);
    address signer = ECDSA.recover(hash, signature);
  • Check for Voter Validity: Ensure that the recovered signer is a valid voter and that the vote corresponds to their intended candidate rankings.

Updates

Lead Judging Commences

inallhonesty Lead Judge
about 1 year ago
inallhonesty Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement

Support

FAQs

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