Skip to main content

Module trusted_proxies

Module trusted_proxies 

Source
Expand description

Whose X-Forwarded-For to believe.

Behind a load balancer every request arrives from the balancer’s address, so the client’s real address is only available in a header the balancer added. The trap is that a header is something any client can send. A server that reads X-Forwarded-For from whoever supplies it has not learned the client’s address; it has let the client choose one. Anything keyed on that address — a rate limiter, an audit log, a block list — is then trivially defeated by a header.

So the header is believed only when the connection came from a proxy that was named in advance:

App::new()?.middleware(TrustProxies::from_config(app.config()))
// or
App::new()?.middleware(TrustProxies::at(["10.0.0.0/8", "172.16.0.0/12"]))

Without this middleware, Request::ip is the address of whoever opened the socket, which is always true even when it is not always useful. With it, and only for a connection from a trusted proxy, it becomes the left-most address in the forwarded chain that the trusted proxies did not themselves add.

The same applies to the scheme. A proxy that terminates TLS forwards a plain HTTP request with X-Forwarded-Proto: https, and without that header an application would generate http:// links on a site that is entirely https://.

TrustProxies::any() exists and is documented as what it is: correct on a platform where nothing but the platform’s own proxy can reach the process — a Heroku dyno, a Cloud Run container, a pod behind an ingress with no other route in — and a hole anywhere else.

Structs§

Forwarded
What a trusted proxy told us about the original client.
TrustProxies