提交 d160a8d6 编写于 作者: M Matthew Draper 提交者: Keenan Brock

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.
上级 14149105
......@@ -143,10 +143,11 @@ def calculate_ip
# - 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
......
......@@ -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
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册