enhancement, security, backend, GSSoC 2026
Summary
StackIt's voting system (POST /api/questions/:id/vote and POST /api/answers/:id/vote) is the backbone of the reputation system. Without rate limiting and atomic idempotency enforcement, a malicious or buggy client can rapidly fire repeated vote requests — inflating or deflating scores through network-level automation. The current implementation relies on application-level checks that are vulnerable to race conditions under concurrency.
Problem
- No per-user, per-resource rate limit exists on vote endpoints.
- Idempotency (the "already voted" check) is enforced only at the application layer — not atomically at the database level — making it vulnerable to race conditions under concurrent requests.
- No cooldown between vote and unvote operations allows reputation farming via rapid vote cycling.
- The endpoint returns
200 OK on duplicate vote attempts, providing no feedback to the frontend that the action was a no-op.
Impact
- Malicious users can automate vote requests to unfairly boost their own answers or tank competitor answers.
- Race conditions can result in duplicate vote records that corrupt the reputation calculation.
Proposed Solution
1. Add express-rate-limit middleware on all vote routes:
// server/middleware/voteLimiter.js
const rateLimit = require('express-rate-limit');
module.exports = rateLimit({
windowMs: 60 * 1000,
max: 10,
keyGenerator: (req) => `vote:${req.user.id}`,
standardHeaders: true,
legacyHeaders: false,
message: {
error: 'Too many voting actions. Please wait before voting again.',
retryAfter: 60,
},
});
2. Add a unique compound index to the Vote model for atomic idempotency at the database level:
// server/models/Vote.js
VoteSchema.index(
{ user: 1, target: 1, targetType: 1 },
{ unique: true }
);
3. Return 409 Conflict (not a silent 200) when a duplicate vote is attempted, so the frontend can accurately update its UI state:
// In the vote controller
try {
await Vote.create({ user: req.user.id, target: id, targetType: 'question', value });
} catch (err) {
if (err.code === 11000) {
return res.status(409).json({ error: 'You have already voted on this item.' });
}
throw err;
}
I am participating in GSSoC 2026. Could you please assign this issue to me?
enhancement, security, backend, GSSoC 2026
Summary
StackIt's voting system (
POST /api/questions/:id/voteandPOST /api/answers/:id/vote) is the backbone of the reputation system. Without rate limiting and atomic idempotency enforcement, a malicious or buggy client can rapidly fire repeated vote requests — inflating or deflating scores through network-level automation. The current implementation relies on application-level checks that are vulnerable to race conditions under concurrency.Problem
200 OKon duplicate vote attempts, providing no feedback to the frontend that the action was a no-op.Impact
Proposed Solution
1. Add
express-rate-limitmiddleware on all vote routes:2. Add a unique compound index to the Vote model for atomic idempotency at the database level:
3. Return
409 Conflict(not a silent 200) when a duplicate vote is attempted, so the frontend can accurately update its UI state:I am participating in GSSoC 2026. Could you please assign this issue to me?