rails/rails — pull request #15568 by edslocomb (2014-06-08 00:45:28+00:00)
Title: Allow multiple trusted networks with differing proxy header behavior (raises IpSpoofAttackError)

request.remote_ip() should not raise ActionDispatch::RemoteIp::IpSpoofAttackError when a request has passed through proxies for two or more private (or otherwise trusted) networks, where one proxy has set the nonstandard HTTP_CLIENT_IP header, and another has set the nonstandard HTTP_X_FORWARDED_FOR header.

As it stands, e.g.:

1. A request originates at 192.168.1.103, and passes through a proxy which sets HTTP_CLIENT_IP to that address.
2. The first proxy then sends the request out from 10.1.1.232, to a second proxy
3. The second proxy prepends this new address to HTTP_X_FORWARDED_FOR, and then sends the request to a Rails server
4. The Rails server sees that both HTTP_CLIENT_IP and HTTP_X_FORWARDED_FOR have been set, so it compares the two addresses in the two headers.
5. Since the addresses are different, Rails raises an ActionDispatch::RemoteIp::IpSpoofAttackError

The fix is to filter trusted IPs before making this comparison (tests included).