DEV Community

kozhevniko
kozhevniko

Posted on

Express trust proxy is a hop count, not a trust policy

Express trust proxy is a hop count, not a trust policy

Express applications frequently run behind a reverse proxy. The trust proxy setting tells Express how to interpret forwarding headers when it derives properties such as req.ip, req.protocol, and req.hostname. The setting is easy to copy into a deployment template and easy to get wrong.

With proxy trust disabled, Express uses the direct socket address. When the setting is enabled, it uses information in headers such as X-Forwarded-For. The documentation warns that the left-most entry can be supplied by the client when the application trusts every hop. Setting trust proxy to true is therefore a broad claim that the application is isolated behind a correctly behaving proxy chain.

What Express trusts

A numeric value is narrower: it tells Express how many proxy hops to trust. That is useful when the topology is stable and every request follows the same path. The number must change when a load balancer, CDN, or sidecar is added. A stale hop count can produce the wrong client address, and a count that is too generous can allow a client-controlled header value to appear trustworthy.

Topology and header risk

Subnet and address-based settings can be more precise than a number. They still require an inventory of immediate proxy addresses and a review of how headers traverse the chain. A list of private ranges may be inaccurate if an unrelated tenant, container network, or internal service can connect directly.

Where the setting matters

The application's security decisions reveal where the setting matters:

  • Rate limits keyed by client address.
  • Admin allowlists and geo restrictions.
  • Audit logs and alert correlation.
  • Secure-cookie and HTTPS redirect logic.
  • Password-reset link generation.
  • Abuse controls that assume a single client identity.

Validation and logging

Test the path from both sides. Send a forged X-Forwarded-For directly to Express and confirm that it cannot become req.ip. Send a request through the approved proxy and confirm that the application records the expected client and protocol. Check every environment, including staging, because a shared application image can inherit the production setting while a different proxy supplies the headers.

Logging should include enough path context to investigate a failed trust decision. If the application logs only the rewritten address, an analyst may not know which proxy supplied it. The edge should log its observed client address and the headers it generated. Application logs can then record the final Express value and the request route.

Keep the setting in configuration owned by the deployment platform rather than scattered across route handlers. Define which proxy provides the client address and which headers are accepted. If the application is ever exposed directly, disable proxy trust for that listener or remove the route from the public network entirely.

trust proxy does not authenticate a proxy. It tells Express how to interpret a header once the request arrives. The safe configuration matches one documented topology, uses the narrowest trust expression available, and has tests that fail when a direct client tries to assert forwarded identity.

References

Top comments (0)