From 8356e51d9e3cd23ae4c46454b3471994f5963933 Mon Sep 17 00:00:00 2001 From: Felix Hellborg Date: Sun, 12 Apr 2026 20:51:20 +0200 Subject: [PATCH] Add out of bounds check for candidate ID upon vote submission. This makes sure that even if the fronted bugs out completely, the system doesn't fail silenlty and the voter may try again --- rustsystem-core/src/lib.rs | 2 ++ rustsystem-server/src/api/voter/vote.rs | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/rustsystem-core/src/lib.rs b/rustsystem-core/src/lib.rs index 9ee0b86..463f569 100644 --- a/rustsystem-core/src/lib.rs +++ b/rustsystem-core/src/lib.rs @@ -44,6 +44,7 @@ pub enum APIErrorCode { InvalidMetaData, InvalidVoteMethod, InvalidVoteLength, + InvalidCandidateId, VotingInactive, SignatureInvalid, @@ -105,6 +106,7 @@ impl APIErrorCode { 409, ), Self::InvalidVoteLength => ("Too many candidates were provided.", 409), + Self::InvalidCandidateId => ("Vote contains an out-of-bounds candidate index.", 422), Self::VotingInactive => ("Vote has already been closed, or it was never opened.", 410), Self::SignatureInvalid => ( diff --git a/rustsystem-server/src/api/voter/vote.rs b/rustsystem-server/src/api/voter/vote.rs index a02ab3e..d79b820 100644 --- a/rustsystem-server/src/api/voter/vote.rs +++ b/rustsystem-server/src/api/voter/vote.rs @@ -42,6 +42,7 @@ impl APIHandler for Submit { validate_metadata(metadata.clone(), round)?; validate_num_choices(choice.clone(), round)?; + validate_candidate_indices(choice.clone(), round)?; validate_signature(validation, round)?; let is_blank = choice.is_none(); @@ -82,6 +83,16 @@ fn validate_num_choices(choice: Option, round: &VoteRound) -> Result<(), Ok(()) } +fn validate_candidate_indices(choice: Option, round: &VoteRound) -> Result<(), APIError> { + if let Some(choices) = choice { + let num_candidates = round.metadata().get_candidates().len(); + if choices.iter().any(|&id| id >= num_candidates) { + return Err(APIError::from_error_code(APIErrorCode::InvalidCandidateId)); + } + } + Ok(()) +} + fn validate_signature( validation: &BallotValidation, round: &mut VoteRound,