Skip to content

fix: add rate limiting to non-friends leaderboard scopes#688

Open
namann5 wants to merge 1 commit into
Coder-s-OG-s:mainfrom
namann5:fix/leaderboard-rate-limit-all-scopes
Open

fix: add rate limiting to non-friends leaderboard scopes#688
namann5 wants to merge 1 commit into
Coder-s-OG-s:mainfrom
namann5:fix/leaderboard-rate-limit-all-scopes

Conversation

@namann5

@namann5 namann5 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds rate limiting to all non-friends leaderboard scopes (\global, \cohort, \language, \ ag, \monthly) in \getLeaderboard.

Problem

Only the \ riends\ scope had rate limiting via
equireUser. All other scopes could be called at high frequency, enabling:

  • Database resource exhaustion via expensive aggregation queries (especially \monthly\ which joins profiles + xp_events)
  • Cache bypass by using different \scopeId\ parameters or concurrent requests

Fix

Added a shared rate limit (30 requests per 60 seconds) for non-friends scopes, applied before any database queries execute. This uses the same
equireUser\ +
ateLimit\ pattern already used for the \ riends\ scope.

The \ riends\ scope retains its existing separate rate limit (10 req/60s) which is stricter due to the additional GitHub API call overhead.

Testing


  • pm run lint\ passes

  • pm run typecheck\ passes (pre-existing @google/genai\ error only)

Closes #657

Closes Coder-s-OG-s#657

Only the friends scope had rate limiting via requireUser. All other
scopes (global, cohort, language, tag, monthly) could be called at
high frequency, enabling database resource exhaustion. Added a shared
rate limit (30 req/60s) for non-friends scopes before any expensive
DB queries execute.
@vercel

vercel Bot commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

@namann5 is attempting to deploy a commit to the codersogs-3057's projects Team on Vercel.

A member of the Team first needs to authorize it.

Comment on lines +128 to +132
if (scope !== 'friends') {
const rlRes = await requireUser({
rateLimit: { namespace: 'leaderboard', limit: 30, windowSec: 60 },
rateLimitMessage: 'too many leaderboard requests, slow down',
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this rate limit check runs before the cache check, so cache hits get throttled too even though they don't touch the db. the friends scope below (line ~190) does it right - rate limit is inside the if (!cached) block, at the point the query actually happens. move this one in there too.

also RATE_LIMIT_TIERS is imported but unused, the {limit:30, windowSec:60} you hardcoded is literally RATE_LIMIT_TIERS.STANDARD, just use that.

@jakharmonika364 jakharmonika364 added the Needs author reply Author need to reply label Jul 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Needs author reply Author need to reply

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Missing rate limiting on non-friends leaderboard scopes enables database resource exhaustion

2 participants