src/reputation/reputation.controller.ts has no @UseGuards anywhere. POST /reputation/:userId/recompute is a write route with no guard at all — any unauthenticated caller can trigger ReputationService.computeAndSave(userId) for any user id, repeatedly, with no rate limiting beyond the app-wide 120-req/min throttle. Each call appends a new row to reputation_snapshots (an append-only table with no upsert/dedup) regardless of whether anything about that user's bounty activity actually changed since the last snapshot.
This is both a data-integrity concern (an attacker can trivially flood reputation_snapshots with thousands of near-identical rows for arbitrary users, degrading getLatest/history query performance and inflating storage) and an information-exposure concern: GET /reputation/:userId and GET /reputation/:userId/history leak a contributor's full computed reputation history (earnings, completion rate, review-time averages, org/language breakdown) with no auth check at all.
Fix: guard GET/history behind JwtAuthGuard at minimum, and restrict recompute further — either to the user themselves, a scheduled job, or a maintainer role — rather than leaving it open to any caller.
src/reputation/reputation.controller.ts has no
@UseGuardsanywhere.POST /reputation/:userId/recomputeis a write route with no guard at all — any unauthenticated caller can triggerReputationService.computeAndSave(userId)for any user id, repeatedly, with no rate limiting beyond the app-wide 120-req/min throttle. Each call appends a new row toreputation_snapshots(an append-only table with no upsert/dedup) regardless of whether anything about that user's bounty activity actually changed since the last snapshot.This is both a data-integrity concern (an attacker can trivially flood
reputation_snapshotswith thousands of near-identical rows for arbitrary users, degradinggetLatest/historyquery performance and inflating storage) and an information-exposure concern:GET /reputation/:userIdandGET /reputation/:userId/historyleak a contributor's full computed reputation history (earnings, completion rate, review-time averages, org/language breakdown) with no auth check at all.Fix: guard
GET/historybehindJwtAuthGuardat minimum, and restrictrecomputefurther — either to the user themselves, a scheduled job, or a maintainer role — rather than leaving it open to any caller.