Skip to content

fix(security): use trusted IP source for rate limiter client key - #875

Open
Esc1200 wants to merge 1 commit into
vibeforge1111:mainfrom
Esc1200:spark/fix-rate-limiter-ip-spoofing
Open

fix(security): use trusted IP source for rate limiter client key#875
Esc1200 wants to merge 1 commit into
vibeforge1111:mainfrom
Esc1200:spark/fix-rate-limiter-ip-spoofing

Conversation

@Esc1200

@Esc1200 Esc1200 commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

Bug: Rate limiter uses spoofable X-Forwarded-For for client identification

Severity: MEDIUM

File: src/lib/server/hosted-ui-auth.ts (lines 186-188)

Problem:
hostedUiAuthClientKey() used the first entry of X-Forwarded-For as the rate limiter client key, prioritizing it over X-Real-IP. Since X-Forwarded-For is a client-set header on the first hop, an attacker can:

  1. Spoof arbitrary IPs in the X-Forwarded-For header
  2. Rotate spoofed IPs to bypass rate limiting entirely
  3. Avoid lockout after repeated failed auth attempts

Fix:

  • Prefer x-real-ip (set by the trusted reverse proxy like nginx) as the primary client key
  • Fall back to x-forwarded-for only when x-real-ip is missing, using the last entry (rightmost) which is set by the trusted proxy closest to the server, not the first entry which is client-controllable
  • Maintain 'unknown' fallback for missing headers

Testing:

  • Rate limiting still functions correctly behind standard reverse proxies
  • Spoofed X-Forwarded-For values from clients no longer affect the rate limiter key

The rate limiter in hostedUiAuthClientKey() prioritized X-Forwarded-For
(first entry) over X-Real-IP. Since X-Forwarded-For is set by the client
on the first hop, an attacker can spoof it to bypass rate limiting by
rotating arbitrary client identifiers.

Fix:
- Prefer x-real-ip (set by the trusted reverse proxy) as the primary key
- If falling back to x-forwarded-for, use the LAST entry (rightmost) which
  is set by the trusted proxy closest to the server, not the first entry
  which is client-controllable
- Maintain 'unknown' fallback for missing headers
ifeoluwaaj pushed a commit to ifeoluwaaj/vibeship-spawner-ui that referenced this pull request Jun 27, 2026
Consolidates a same-author path-redaction series:
- Remove tracePath from creator mission GET response (vibeforge1111#877)
- Remove server path from mission active POST response (vibeforge1111#876)
- Remove rawResponse field from analyze error response (vibeforge1111#874)
- Remove x-spark-preview-root header leaking server path (vibeforge1111#873)
- Use trusted x-real-ip / last x-forwarded-for entry for the
  rate-limiter client key (vibeforge1111#875)

Surviving-line indentation normalized back to file style (the patches
bundled an over-indentation reflow of untouched lines).

Co-authored-by: Esc1200 <Esc1200@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant