1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

When all IPs are trusted, use the furthest away

Scenario: we have a REMOTE_ADDR of `127.0.0.1`, and X-Forwarded-For is
`A, B, C`.

Without any relevant trust, the `remote_ip` is `C`.

If `C` is trusted, then the `remote_ip` is `B`.

If `B` and `C` are trusted, then the `remote_ip` is `A`.

If all of `A`, `B`, and `C` are trusted, then the `remote_ip` should
still be `A`: if our trust was sufficient to get that far out before,
trusting something else should not have us fall back to `127.0.0.1`.

It is this last situation that we're correcting here:

We trust `A` to give us accurate X-Forwarded-For information, yet it has
chosen to leave it unset. Therefore, `A` is telling us that it is itself
the client.
This commit is contained in:
Matthew Draper 2014-04-05 02:44:16 +10:30 committed by Keenan Brock
parent 1414910502
commit d160a8d637
2 changed files with 16 additions and 8 deletions

View file

@ -143,10 +143,11 @@ module ActionDispatch
# - X-Forwarded-For will be a list of IPs, one per proxy, or blank
# - Client-Ip is propagated from the outermost proxy, or is blank
# - REMOTE_ADDR will be the IP that made the request to Rack
ips = [forwarded_ips, client_ips, remote_addr].flatten.compact
ips = [forwarded_ips, client_ips].flatten.compact
# If every single IP option is in the trusted list, just return REMOTE_ADDR
filter_proxies(ips).first || remote_addr
# If every single IP option is in the trusted list, return the IP
# that's furthest away
filter_proxies(ips + [remote_addr]).first || ips.last || remote_addr
end
# Memoizes the value returned by #calculate_ip and returns it for

View file

@ -77,6 +77,10 @@ class RequestIP < BaseRequestTest
"HTTP_X_FORWARDED_FOR" => "3.4.5.6"
assert_equal "3.4.5.6", request.remote_ip
request = stub_request "REMOTE_ADDR" => "127.0.0.1",
"HTTP_X_FORWARDED_FOR" => "172.31.4.4, 10.0.0.1"
assert_equal "172.31.4.4", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,unknown"
assert_equal "3.4.5.6", request.remote_ip
@ -89,6 +93,9 @@ class RequestIP < BaseRequestTest
request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6,10.0.0.1"
assert_equal "3.4.5.6", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "172.31.4.4, 10.0.0.1"
assert_equal "172.31.4.4", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "3.4.5.6, 10.0.0.1, 10.0.0.1"
assert_equal "3.4.5.6", request.remote_ip
@ -96,7 +103,7 @@ class RequestIP < BaseRequestTest
assert_equal "3.4.5.6", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "unknown,192.168.0.1"
assert_nil request.remote_ip
assert_equal "192.168.0.1", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "9.9.9.9, 3.4.5.6, 172.31.4.4, 10.0.0.1"
assert_equal "3.4.5.6", request.remote_ip
@ -161,7 +168,7 @@ class RequestIP < BaseRequestTest
assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "unknown,::1"
assert_nil request.remote_ip
assert_equal "::1", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "2001:0db8:85a3:0000:0000:8a2e:0370:7334, fe80:0000:0000:0000:0202:b3ff:fe1e:8329, ::1, fc00::, fc01::, fdff"
assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
@ -207,7 +214,7 @@ class RequestIP < BaseRequestTest
assert_equal "3.4.5.6", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "67.205.106.73,unknown"
assert_nil request.remote_ip
assert_equal "67.205.106.73", request.remote_ip # change
request = stub_request "HTTP_X_FORWARDED_FOR" => "9.9.9.9, 3.4.5.6, 10.0.0.1, 67.205.106.73"
assert_equal "3.4.5.6", request.remote_ip
@ -226,10 +233,10 @@ class RequestIP < BaseRequestTest
request = stub_request "REMOTE_ADDR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,::1",
"HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
assert_equal "::1", request.remote_ip
assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "unknown,fe80:0000:0000:0000:0202:b3ff:fe1e:8329"
assert_nil request.remote_ip
assert_equal "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", request.remote_ip
request = stub_request "HTTP_X_FORWARDED_FOR" => "fe80:0000:0000:0000:0202:b3ff:fe1e:8329,2001:0db8:85a3:0000:0000:8a2e:0370:7334"
assert_equal "2001:0db8:85a3:0000:0000:8a2e:0370:7334", request.remote_ip