diff --git a/src/shared/lib/rateLimit.js b/src/shared/lib/rateLimit.js index 5d1a9ba..63e3030 100644 --- a/src/shared/lib/rateLimit.js +++ b/src/shared/lib/rateLimit.js @@ -122,12 +122,12 @@ export function getIpFromHeaders(headersList) { const realIp = headersList.get('x-real-ip')?.trim(); if (realIp && isValidIp(realIp)) return realIp; } - // Fallback when no trusted proxy is configured. - // Callers (router.js, authActions.js) treat 'unknown' as a signal to suspend - // rate limiting rather than collapse all traffic into one shared bucket — which - // would allow a single attacker to exhaust the quota and deny service globally. + // In development, use loopback so rate limiting stays active and the + // "IP cannot be determined" warning is not emitted. + // In production without a trusted proxy, return 'unknown' to suspend rate + // limiting rather than collapse all traffic into one shared bucket. // Configure ZEN_TRUST_PROXY=true behind a verified reverse proxy. - return 'unknown'; + return process.env.NODE_ENV === 'development' ? '127.0.0.1' : 'unknown'; } /** @@ -143,7 +143,7 @@ export function getIpFromRequest(request) { const realIp = request.headers.get('x-real-ip')?.trim(); if (realIp && isValidIp(realIp)) return realIp; } - return 'unknown'; + return process.env.NODE_ENV === 'development' ? '127.0.0.1' : 'unknown'; } /**