rack/rack — pull request #705 by stevehodgkiss (2014-06-24 02:33:07+00:00)
Title: Prevent IP spoofing via X-Forwarded-For and Client-IP headers

By specifying the same IP address in `X-Forwarded-For` and `Client-IP` an attacker is able to easily spoof the value of `request.ip`. This affects deployments where a proxy is involved (where `REMOTE_ADDR` is recognised as a trusted proxy) and that proxy isn't configured to remove any `Client-IP` headers.

To reproduce `curl -IH 'X-Forwarded-For: 6.6.6.6' -H 'Client-IP: 6.6.6.6' http://site` and observe that the log entry includes 6.6.6.6 as the request IP.

In setups where a proxy is involved, the value of `request.ip` should be the IP address after the last trusted proxy IP address in `X-Forwarded-For` (from right to left). I don't see any specs covering when Client-IP should be returned from `request.ip`, only a spec covering the ip spoofing protection logic, which is trivial to work around. Does anyone know why Client-IP is involved here?

This change to rack was introduced in https://github.com/rack/rack/pull/192. The logic appears to have originally come from this commit in Rails back in 2008 https://github.com/rails/rails/commit/edfa195e2ace7b4fb.

If there is a need to support forwarding headers other than `X-Forwarded-For`, I think that should be something that can be configured or overridden somehow (defaulting to `X-Forwarded-For`), not something we should have to guess based on headers present in each request.