[interchange] Trust only the last hop before a trusted proxy, when multiples exist
Jon Jensen <[email protected]>
| Newsgroups | gmane.comp.web.interchange.cvs |
|---|---|
| Message-ID | <[email protected]> |
commit 21227cd3c1d2c345f431fc0f35cfbd6699b46518 Author: Jon Jensen <[email protected]> Date: Tue Dec 21 16:49:09 2010 -0700 Trust only the last hop before a trusted proxy, when multiples exist The original implementation here trusted that the X-Forwarded-For header was trustworthy, and when multiple intermediate proxies (or forgeries) were present, you could end up with an internal IP address on the remote network listed, or something entirely bogus. When multiple proxies are present, trust only the one that connected to our trusted proxy. Even though that doesn't get us to the "original" IP address, it's reliable and public, and the one we would've seen if we weren't using TrustProxy at all. lib/Vend/Server.pm | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) --- diff --git a/lib/Vend/Server.pm b/lib/Vend/Server.pm index 85b95c3..b6453e9 100644 --- a/lib/Vend/Server.pm +++ b/lib/Vend/Server.pm @@ -132,8 +132,9 @@ sub populate { and ($CGI::remote_addr =~ $Global::TrustProxy or $CGI::remote_host =~ $Global::TrustProxy) and $ip = $cgivar->{HTTP_X_FORWARDED_FOR}) { - # trim off intermediate proxies in comma-separated list - $ip =~ s/,.*//; + # trust only the last hop's IP address before our trusted proxy + # when multiples are present in a comma-separated list + $ip =~ s/.*,//; $ip =~ s/^\s+//; $ip =~ s/\s+$//; if ($ip =~ /^\d\d?\d?\.\d\d?\d?\.\d\d?\d?\.\d\d?\d?$/) { $CGI::remote_addr = $ip;