Skip to content

Rate limiting keys on req.ip with no trust-proxy configuration — collapses to a single bucket behind a reverse proxy #528

Description

@sshdopey

Where: src/middleware/rateLimit.ts (uses express-rate-limit's default
keyGenerator, which reads req.ip), and the absence of any
app.set("trust proxy", ...) call anywhere in src/index.ts or elsewhere.

What's wrong: without trust proxy configured, Express's req.ip
resolves to req.socket.remoteAddress — the direct TCP peer. In any
production deployment that sits behind a reverse proxy / load balancer / CDN
(the common case for a Node backend, and implied by the codebase's own
X-Forwarded-For-reading code in ipWhitelist.ts), req.socket.remoteAddress
is the proxy's IP for every single client. publicLimiter/adminLimiter
(src/middleware/rateLimit.ts) therefore key every client into the same
rate-limit bucket in that topology.

Impact: in production behind a typical proxy, one heavy or abusive client
exhausts the shared rate-limit bucket for all clients (denial of service
for legitimate traffic), while the whole point of per-IP rate limiting —
isolating one bad actor — silently doesn't work. This is the flip side of
the ipWhitelist.ts X-Forwarded-For issue: that one is unsafe because it
manually trusts a spoofable header without proxy config; this one is broken
because express-rate-limit correctly doesn't trust anything without proxy
config, so it under-trusts in the real deployment topology.

Suggested fix: configure app.set("trust proxy", ...) to the exact
number of trusted hops (or a specific CIDR) matching the real deployment,
then let both express-rate-limit and ipWhitelist.ts derive the client IP
from Express's own req.ip instead of hand-parsing headers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Stellar WaveIssues in the Stellar wave program

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions