Summary
The public API rate limiter uses a process-local Map, keys limits by client IP, trusts forwarded headers directly, and applies the import-mode rate boost before API-key authentication.
Evidence
- apps/web/src/lib/server/domains/api/rate-limit.ts:1-10 documents the in-memory, proxy-header-trusting design.
- apps/web/src/lib/server/domains/api/rate-limit.ts:17 stores limiter state in a local Map.
- apps/web/src/lib/server/domains/api/rate-limit.ts:58-92 limits by IP and import mode.
- apps/web/src/lib/server/domains/api/rate-limit.ts:102-121 trusts cf-connecting-ip, x-forwarded-for, and x-real-ip.
- apps/web/src/lib/server/domains/api/auth.ts:96-99 applies the limiter before authenticating the API key.
- apps/web/src/lib/server/domains/api/auth.ts:97-98 reads x-import-mode before auth.
- apps/web/src/lib/server/domains/api/auth.ts:120-122 only later confirms import mode is allowed for admin keys.
Impact
Multi-replica deployments can bypass limits by spreading traffic across instances. Directly exposed deployments can spoof forwarded headers. NATed customers can be rate-limited together. Unauthenticated callers can request the import-mode limit bucket before auth by sending x-import-mode: true.
Recommended fix
Move API limiting to Redis or another shared store. Use separate buckets for pre-auth failures, verified API key ID, principal ID, and IP. Only apply import-mode limits after successful admin authentication. Trust forwarded headers only when the immediate peer is a configured trusted proxy.
Acceptance criteria
- Rate limits are shared across app replicas.
- Verified API-key requests are limited primarily by API key or principal, not only IP.
- Invalid-auth attempts have a strict pre-auth bucket.
- Import-mode rate boosts apply only after admin key validation.
- Forwarded headers are ignored unless the request came through a trusted proxy.
- Tests cover spoofed x-forwarded-for, x-import-mode before auth, and multiple API keys behind one IP.
Summary
The public API rate limiter uses a process-local Map, keys limits by client IP, trusts forwarded headers directly, and applies the import-mode rate boost before API-key authentication.
Evidence
Impact
Multi-replica deployments can bypass limits by spreading traffic across instances. Directly exposed deployments can spoof forwarded headers. NATed customers can be rate-limited together. Unauthenticated callers can request the import-mode limit bucket before auth by sending x-import-mode: true.
Recommended fix
Move API limiting to Redis or another shared store. Use separate buckets for pre-auth failures, verified API key ID, principal ID, and IP. Only apply import-mode limits after successful admin authentication. Trust forwarded headers only when the immediate peer is a configured trusted proxy.
Acceptance criteria