-
-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Description
This relates to #5104
Firstly, wonderful software that really makes great default decisions. Thanks for caddy.
I suggest adding a configuration parameter to trusted_proxies which would allow deciding the depth at which the Client IP is in the X-Forwarded-For (referred to as XFF in this issue) stack of IPs. This is a feature request but also a bug/security issue. Currently, it is very easy to misuse trusted_proxies due to how XFF handling is implemented in caddy.
In the original PR, it is noted:
This implementation takes the left-most, first valid IP.
Taking the left-most value is actually the least trustworthy value in nearly all cases. Wikipedia entry re: XFF:
Since it is easy to forge an X-Forwarded-For field the given information should be used with care. The right-most IP address is always the IP address that connects to the last proxy, which means it is the most reliable source of information.
And since adam-p published his article on XFF, MDN has since updated their documentation as well to reflect the security risk in trusting the left-most IP address (thanks to a PR from adam-p).
Recommendation
There are two ways to manage XFF headers safely. The first is by specifying the depth at which your caddy reverse proxy exists (trusted proxy count), and the second is finding the first right-most IP address that isn't in your trusted proxy list (trust proxy list).
Currently caddy pulls the left-most valid IP address. This is not how most reverse proxies work with the header. There is only 1 reverse proxy I know of that behaves very incorrectly, which is Microsoft's IIS. It inserts previous hops to the right of the header instead of the left, which would make finding the left-most the appropriate approach. Instead, caddy should apply the same logic but find the right-most untrusted address. This would be the second Trusted proxy list approach, described above.
However to maintain backwards compatibility, you can also consider adding the Trusted proxy count option. This is as simple as defining a number that specifies how from from the right is the client IP address in the XFF header.
e.g. a header value of X-Forwarded-For: <spoofed address>, <client address>, <proxy 1 address>, <proxy 2 address>, we would use xff_depth 3 to pull the real client_ip address out and ignore the spoofed address.
Right now, the implementation of trusted_proxies means caddy can never safely extract the client IP while behind an AWS Application Load Balancer. See this documentation from AWS on how values are forwarded.