Multiple votes per user possible in the forum pallet via `vote_on_poll`
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 25/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Stale
- Tech stack
- rust
- Domain
- blockchain
Research direction
Start in runtime-modules/forum/src/lib.rs by reading vote_on_poll and ensure_vote_is_valid, then inspect how poll_alternatives and thread state are stored. Determine how prior voters, vote anonymity, and any required deposit should be represented. Done means a user cannot submit more than one vote for a poll and the behavior is covered by the forum pallet's existing validation expectations.
Written by the indexing model from the issue text.
Description
Summary
The vote_on_poll extrinsic in forum pallet does not check whether a user has already voted for a specific poll. This will enable a malicious forum user to submit an arbitrary number of votes and therefore manipulate the poll's result.
Issue Details
In runtime-modules/forum/src/lib.rs the vote_on_poll extrinsic can be used by forum users to vote on a specific PollAlternative by submitting it's index via this extrinsic. This extrinsic performs some validity checks via the ensure_vote_is_valid function, but this function only checks whether the poll exists and if it is not expired. Therefore a malicious forum user may submit arbitrary amount of votes and manipulate the poll's result.
/// Check the vote is valid
fn ensure_vote_is_valid(
thread: Thread<ForumUserId<T>, T::CategoryId, T::Moment, T::Hash>,
index: u32,
) -> Result<Poll<T::Moment, T::Hash>, Error<T>> {
// Ensure poll exists
let poll = thread.poll.ok_or(Error::<T>::PollNotExist)?;
// Poll not expired
if poll.end_time < <pallet_timestamp::Module<T>>::now() {
Err(Error::<T>::PollCommitExpired)
} else {
let alternative_length = poll.poll_alternatives.len();
// The selected alternative index is valid
if index as usize >= alternative_length {
Err(Error::<T>::PollData)
} else {
Ok(poll)
}
}
}
Risk
A malicious forum user can submit an arbitrary number of votes and therefore manipulate a poll.
Mitigation
We suggest mitigating this by adding a tracking mechanism to identify which users have already voted. One possible implementation of this would be to add the voting users (forum_used_id) to the poll_alternatives field that is saved in storage. This way it can be checked whether forum_used_id already exists in any of the poll_alternatives before saving their vote. Furthermore, if the anonymity of the user's votes matter in this use case, the votes can be stored per "thread" instead of "alternatives".
Additionally, since this new implementation will store the votes on-chain, a deposit will also be required.
- Dominant language
- No language data
- Stars
- 2
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from Joystream/audits
-
S2 - moderate
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
S1 - low
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
S1 - low
Difficulty 4/5 3-5 days Newbie friendliness 35/100
-
S3 - high
Difficulty 5/5 Over a week Newbie friendliness 25/100
-
S3 - high
Difficulty 4/5 3-5 days Newbie friendliness 35/100
All issues in Joystream/audits
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
blinklabs-io/bursa#904 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
rust-bitcoin/rust-bitcoin#6908 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Merit-Systems/x402scan#1215 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
Uniswap/default-token-list#2585 ·