question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Improve handling of X-Forwarded-For and the contract of RequestHeader.remoteAddress

See original GitHub issue

Play version: 2.2.1

The current behavior of RequestHeader.remoteAddress is described in the Scaladoc:

If the X-Forwarded-For header is present, then this method will return the value in that header if either the local address is 127.0.0.1, or if trustxforwarded is configured to be true in the application configuration file.

There are two major problems with this:

  1. The X-Forwarded-For can contain a comma-separated list of addresses - not just one address as the current implementation assumes. See wiki or the spec.
  2. 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-For by 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-For list and the RequestHeader.remoteAddress should be the rightmost untrusted proxy in that list
  • the default trusted proxies should be loopback addresses for IPv4 and IPv6.

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:5 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
jropercommented, Nov 27, 2013

Completely agree. There is a draft specification for a new Forwarded header. 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 be 127.0.0.1,::1. So for example, the following: 100.101.102.0/24,2001:db8:1234::/48,::1,127.0.0.1 will match anything in the IPv4 100.101.102.X subnet, the IPv6 2001:db8:1234:X:X:X:X:X subnet, the IPv6 loopback address, and the IPv4 loopback address. This will be used by all X-Forwarded-* and in future Forwarded header processing to work out what to trust. When being applied to X-Forwarded-*, if the remote address validates, we should work out what the right based index of the first X-Forwarded-For IP address is that we don’t trust, and then use the value of the corresponding right based index in the other X-Forwarded-* headers. So, if I have a request from 127.0.0.1 with headers:

X-Forwarded-For:  31.32.33.34, 172.100.3.8, 192.168.1.10
X-Forwarded-Proto: https, http, http
X-Forwarded-Host: some.other.host, my.site.com, my.internal.proxy.com

And it was established that 127.0.0.1 and 192.168.1.10 were both trusted proxies, then the remote IP address would be 172.100.3.8, the protocol would be http, and the host would be my.site.com. This would be equivalent to the following Forwarded header in the new spec:

Forwarded: for=31.32.33.34;proto=https;host=some.other.host
Forwarded: for=172.100.3.8;proto=http;host=my.site.com
Forwarded: for=192.168.1.10;proto=http;host=my.internal.proxy.com

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 - Whether X-Forwarded-For or Forwarded: for= header support is enabled. Defaults forwarded.all.enabled. forwarded.proto.enabled - Whether X-Forwarded-Proto or Forwarded: proto= header support is enabled. Defaults to forwarded.all.enabled. forwarded.host.enabled - Whether X-Forwarded-Host or Forwarded: host= header support is enabled. Defaults to forwarded.all.enabled. Note, we currently don’t support this in any form. forwarded.by.enabled - Whether X-Forwarded-Server or Forwarded: by= header support is enabled. Defaults to forwarded.all.enabled. Note, we currently don’t support this in any form.

0reactions
martinpallmanncommented, Oct 15, 2014

Build is now ok.

The config params are case sensitive. Should that be changed?

Read more comments on GitHub >

github_iconTop 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 >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found