Skip to content

Commit 84e878f

Browse files
authored
fix: secure track-user ip rate limiting to prevent mongodb exhaustion (JhaSourav07#2000)
## Description Fixes JhaSourav07#1991 This PR resolves the critical "Unauthenticated MongoDB Exhaustion / Denial of Wallet" vulnerability in the `/api/track-user` endpoint. By default, the `req.headers.get('x-forwarded-for')` header can be easily spoofed by malicious clients. Vercel automatically appends the true client IP to the end of this header chain and also provides it securely in the `x-real-ip` header. This PR updates the rate-limiting logic to properly prioritize the un-spoofable edge-provided IP (`x-real-ip` or the last IP in the `x-forwarded-for` chain). This effectively blocks attackers from bypassing the `trackUserRateLimiter` to flood the MongoDB instance. ## Pillar - [ ] dYZ" Pillar 1 ?" New Theme Design - [ ] dY"? Pillar 2 ?" Geometric SVG Improvement - [ ] dY ? Pillar 3 ?" Timezone Logic Optimization - [x] dY>,? Other (Bug fix, refactoring, docs) ## Visual Preview N/A (Backend Security Fixes) ## Checklist before requesting a review: - [x] I have read the `CONTRIBUTING.md` file. - [x] I have tested these changes locally (`localhost:3000/api/streak?user=YOUR_USERNAME`). - [x] I have run `npm run format` and `npm run lint` locally and resolved all errors (CI will fail otherwise). - [x] My commits follow the Conventional Commits format (e.g., `feat(themes): ...`, `fix(calculate): ...`). - [x] I have updated `README.md` if I added a new theme or URL parameter. - [x] I have started the repo. - [x] I have made sure that i have only one commit to merge in this PR. - [x] The SVG output matches the CommitPulse "premium quality" aesthetic standard (no raw elements, smooth animations, correct fonts). - [x] (Recommended) I joined the CommitPulse Discord community for contributor discussions, mentorship, and faster PR support.
2 parents de6701b + d58687b commit 84e878f

1 file changed

Lines changed: 6 additions & 2 deletions

File tree

app/api/track-user/route.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@ import { User } from '@/models/User';
44
import { trackUserRateLimiter } from '@/lib/rate-limit';
55

66
export async function POST(req: Request) {
7-
// Get IP for rate limiting
8-
const ip = req.headers.get('x-forwarded-for') || req.headers.get('x-real-ip') || 'unknown';
7+
// Get IP for rate limiting.
8+
// x-real-ip is provided by Vercel/Nginx as the true client IP.
9+
// We fall back to the LAST IP in the x-forwarded-for chain, which is appended by the Vercel proxy.
10+
const forwardedFor = req.headers.get('x-forwarded-for');
11+
const fallbackIp = forwardedFor ? forwardedFor.split(',').pop()?.trim() : 'unknown';
12+
const ip = req.headers.get('x-real-ip') || fallbackIp || 'unknown';
913

1014
if (ip !== 'unknown' && !(await trackUserRateLimiter.check(ip))) {
1115
return NextResponse.json(

0 commit comments

Comments
 (0)