Skip to content

[Bug] public-api: rate limiter sets validate.trustProxy: false but app.set('trust proxy', 1) is not applied, causing all cloud-deployed clients to share one rate-limit bucket #248

Description

@anshul23102

Bug Summary

The public API rate limiter in apps/public-api/src/middlewares/api_usage.js is configured with:

const limiter = rateLimit({
    windowMs: 15 * 60 * 1000,
    max: 100,
    validate: {
        xForwardedForHeader: false,
        trustProxy: false
    }
});

Setting validate.trustProxy: false suppresses the express-rate-limit warning about proxy trust but does NOT configure Express to trust X-Forwarded-For headers. When the public API server is deployed behind a load balancer or reverse proxy (which is the case on Render, as indicated by render.yaml), all incoming requests arrive at the Node.js process with the same internal load-balancer IP as req.socket.remoteAddress.

Because app.set('trust proxy', 1) is absent from the public API Express setup, express-rate-limit keys every request on the same internal IP. The effect is that all SDK users on the platform share a single rate-limit counter: once any combination of users makes 100 requests in 15 minutes, every other user is throttled as well. Conversely, a single abusive client can exhaust the shared bucket for all users by making 100 rapid requests.

The dashboard API correctly sets app.set('trust proxy', 1) (line 17 of apps/dashboard-api/src/app.js), but the public API does not.

Steps to Reproduce

  1. Deploy the public API behind a load balancer.
  2. Send 101 requests from two different client IPs.
  3. Observe that the 101st request from Client B is rate-limited even though Client B has only made 1 request.

Expected Behavior

The public API should set app.set('trust proxy', 1) to correctly extract the real client IP from the X-Forwarded-For header, so each client is rate-limited independently.

Affected Files

  • apps/public-api/src/app.js: missing app.set('trust proxy', 1)
  • apps/public-api/src/middlewares/api_usage.js: validate.trustProxy: false suppresses the warning without fixing the root issue

@geturbackend I would like to work on this issue. Could you please assign/ it to me? Contributing under NSoC '26.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions