Feature and its Use Cases
Description
UpdateEloAfterDebate in backend/controllers/profile_controller.go (lines 352-381) reads winnerId and loserId straight from the request body and updates both users' ratings with no verification that:
- the caller was a participant in any debate,
- a debate between those users actually happened,
- the caller isn't naming themselves as winner repeatedly.
It is also a plain FindOne → $set read-modify-write with no transaction, so concurrent calls lose updates.
Additional Context
Impact
Any logged-in user can farm rating (or zero out other players) with a few curl calls, making the leaderboard meaningless.
Suggested Fix
Derive winner/loser server-side from the stored debate result (the websocket/judge flow already knows the outcome) and remove the client-supplied IDs. Use an atomic update ($inc or optimistic concurrency on a version field).
Code of Conduct
Feature and its Use Cases
Description
UpdateEloAfterDebateinbackend/controllers/profile_controller.go(lines 352-381) readswinnerIdandloserIdstraight from the request body and updates both users' ratings with no verification that:It is also a plain FindOne →
$setread-modify-write with no transaction, so concurrent calls lose updates.Additional Context
Impact
Any logged-in user can farm rating (or zero out other players) with a few
curlcalls, making the leaderboard meaningless.Suggested Fix
Derive winner/loser server-side from the stored debate result (the websocket/judge flow already knows the outcome) and remove the client-supplied IDs. Use an atomic update (
$incor optimistic concurrency on a version field).Code of Conduct