T09 · Insecure Skill Coding Practices
Error
- Location
- src/voting-consensus.js:120
- Finding
- Consensus Manipulation Through Unvalidated Vote Weights and Confidence Values## Vulnerability Details **File Location**: `src/voting-consensus.js:120-127, 181-212` **Vulnerability Type**: Improper input validation in security-sensitive consensus calculations **Risk Level**: High ### Vulnerable Code ```javascript const voteRecord = { voterId, decision: vote.decision || 'abstain', confidence: vote.confidence ?? 0.5, weight: vote.weight ?? 1, reason: vote.reason || '', metadata: vote.metadata || {}, timestamp: Date.now() }; session.votes.set(voterId, voteRecord); ``` ```javascript let totalWeight = 0; let totalConfidence = 0; for (const vote of votes) { if (counts[vote.decision]) { counts[vote.decision].count++; counts[vote.decision].weight += vote.weight; counts[vote.decision].confidence += vote.confidence * vote.weight; counts[vote.decision].voters.push({ voterId: vote.voterId, confidence: vote.confidence, reason: vote.reason }); } totalWeight += vote.weight; totalConfidence += vote.confidence * vote.weight; } // Calculate weighted average confidence const avgConfidence = totalWeight > 0 ? totalConfidence / totalWeight : 0; // Find the winning decision let winningDecision = 'abstain'; let maxWeight = 0; for (const [decision, data] of Object.entries(counts)) { if (decision !== 'abstain' && data.weight > maxWeight) { maxWeight = data.weight; winningDecision = decision; } } // Calculate agreement const winningWeight = counts[winningDecision].weight; const agreement = totalWeight > 0 ? winningWeight / totalWeight : 0; // Calculate average confidence for the winning decision const winningConfidence = winningWeight > 0 ? counts[winningDecision].confidence / winningWeight : 0; ``` ### Technical Analysis The public `vote()` method accepts `decision`, `confidence`, and `weight` without validating their types, ranges, or finiteness. The values are then used directly in consensus arithmetic. An untrusted voter can submit: - A negative weight to reduce ...[truncated 2151 chars]
- Remediation
- ## Remediation Suggestions 1. Validate every vote before storing it: - Permit only `approve`, `reject`, and `abstain`. - Require `Number.isFinite(vote.confidence)` and a value in `[0,1]`. - Require `Number.isFinite(vote.weight)`, a strictly positive value, and an administrator-defined maximum. 2. Do not trust weights supplied by voters. Resolve weights from a server-side voter registry or immutable session policy. 3. Authenticate and authorize voter identities before accepting votes. 4. Define whether a voter may replace an existing vote. If replacement is permitted, ensure statistics and audit records distinguish replacement from a new vote. 5. Reject any result whose total weight is non-finite or non-positive. 6. Assert that calculated agreement and confidence are finite and within `[0,1]` before consensus evaluation. 7. Add adversarial tests covering negative weights, zero weights, excessive weights, `NaN`, `Infinity`, invalid decisions, duplicate voters, and malformed confidence values.
