Improve handling of X-Forwarded-For and the contract of RequestHeader.remoteAddress
See original GitHub issuePlay version: 2.2.1
The current behavior of RequestHeader.remoteAddress is described in the Scaladoc:
If the
X-Forwarded-Forheader is present, then this method will return the value in that header if either the local address is 127.0.0.1, or iftrustxforwardedis configured to be true in the application configuration file.
There are two major problems with this:
- The
X-Forwarded-Forcan contain a comma-separated list of addresses - not just one address as the current implementation assumes. See wiki or the spec. - It does not handle the IPv6 loopback address (
0:0:0:0:0:0:0:1) the same way as the IPv4 one (127.0.0.1).
Also, currently there is no way to disable this feature through configuration.
IMHO the correct way to handle this would be to make this feature more configurable:
- introduce a configuration value that would disable this feature and let the application handle
X-Forwarded-Forby itself or figure out another way to make this application-customizable - the implementation should be able to handle a configurable list of trusted proxies that would be removed from the end of the
X-Forwarded-Forlist and theRequestHeader.remoteAddressshould be the rightmost untrusted proxy in that list - the default trusted proxies should be loopback addresses for IPv4 and IPv6.
Issue Analytics
- State:
- Created 10 years ago
- Comments:5 (4 by maintainers)
Top Results From Across the Web
X-Forwarded-For - HTTP - MDN Web Docs
The X-Forwarded-For (XFF) request header is a de-facto standard header for identifying the originating IP address of a client connecting to ...
Read more >Insert the IP address of the client in the request header
To insert the client IP address in the client request by using the GUI. Navigate to Traffic Management > Load Balancing > Services,...
Read more >HTTP headers and Classic Load Balancers
The X-Forwarded-For request header is automatically added and helps you identify the IP address of a client when you use an HTTP or...
Read more >How to get X-Forwarded-For IP addresses in Apache Web ...
This tutorial will show you how to get X-Forwarded-For IP addresses in Apache Web Server. Read now & Identify the originating client IP ......
Read more >HTTP at the Edge: Determining Remote Address - Aaron Bedra
It's time to address the last item on the X-Forwarded-For processing checklist. We need to verify that the address extracted from the header...
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found

Completely agree. There is a draft specification for a new
Forwardedheader. While I don’t think we should implement that yet - there’s every chance it will change before becoming a standard, we should consider it’s design in what we implement, and make sure we implement something that will be compatible:http://tools.ietf.org/html/draft-ietf-appsawg-http-forwarded-10
So, given that, I think we should have the following configuration:
forwarded.trusted.proxies- A comma separated list of IPv4 and/or IPv6 proxy addresses, optionally with address block size. By default, it will be127.0.0.1,::1. So for example, the following:100.101.102.0/24,2001:db8:1234::/48,::1,127.0.0.1will match anything in the IPv4100.101.102.Xsubnet, the IPv62001:db8:1234:X:X:X:X:Xsubnet, the IPv6 loopback address, and the IPv4 loopback address. This will be used by allX-Forwarded-*and in futureForwardedheader processing to work out what to trust. When being applied toX-Forwarded-*, if the remote address validates, we should work out what the right based index of the firstX-Forwarded-ForIP address is that we don’t trust, and then use the value of the corresponding right based index in the otherX-Forwarded-*headers. So, if I have a request from127.0.0.1with headers:And it was established that
127.0.0.1and192.168.1.10were both trusted proxies, then the remote IP address would be172.100.3.8, the protocol would behttp, and the host would bemy.site.com. This would be equivalent to the followingForwardedheader in the new spec:forwarded.all.enabled- Whether all types of forwarded headers are enabled. Defaults to true (this is safe since by default we accept only loopback addresses).forwarded.for.enabled- WhetherX-Forwarded-FororForwarded: for=header support is enabled. Defaultsforwarded.all.enabled.forwarded.proto.enabled- WhetherX-Forwarded-ProtoorForwarded: proto=header support is enabled. Defaults toforwarded.all.enabled.forwarded.host.enabled- WhetherX-Forwarded-HostorForwarded: host=header support is enabled. Defaults toforwarded.all.enabled. Note, we currently don’t support this in any form.forwarded.by.enabled- WhetherX-Forwarded-ServerorForwarded: by=header support is enabled. Defaults toforwarded.all.enabled. Note, we currently don’t support this in any form.Build is now ok.
The config params are case sensitive. Should that be changed?