Trust the reverse proxy for real client IP resolution

Without Express's trust-proxy setting, req.ip resolves to the load
balancer's own connecting IP for every request in production, not
the real client IP. That silently broke per-IP rate limiting: every
user behind the same proxy shared one 100-requests-per-60-seconds
throttler bucket instead of getting their own, so any real traffic
volume (the dashboard alone fires ~6 requests per load) could 429
everyone, including on login/registration.
This commit is contained in:
MOHAN 2026-08-26 20:49:45 +05:30
parent 40902f001a
commit 90dfe65fa3

View File

@ -25,6 +25,16 @@ async function bootstrap() {
rawBody: true, // Required for Stripe webhook signature verification rawBody: true, // Required for Stripe webhook signature verification
}); });
// ─── Trust the reverse proxy / load balancer in front of this app ─────────
// Without this, Express's req.ip (and therefore per-IP rate limiting) sees
// the proxy's own connecting IP for every request instead of the real
// client IP, so every user behind the same proxy shares one rate-limit
// bucket. Only relevant in production, where a proxy is expected; in local
// dev the app is hit directly.
if (isProduction) {
app.getHttpAdapter().getInstance().set("trust proxy", 1);
}
// ─── Security headers ───────────────────────────────────────────────────── // ─── Security headers ─────────────────────────────────────────────────────
const scriptSrc = isProduction ? ["'self'"] : ["'self'", "'unsafe-inline'"]; const scriptSrc = isProduction ? ["'self'"] : ["'self'", "'unsafe-inline'"];
const styleSrc = isProduction ? ["'self'"] : ["'self'", "'unsafe-inline'"]; const styleSrc = isProduction ? ["'self'"] : ["'self'", "'unsafe-inline'"];