-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Added new Forwarded header support for Request::getClientIps #11379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
tony-co
commented
Jul 11, 2014
Q | A |
---|---|
Bug fix? | no |
New feature? | no |
BC breaks? | no |
Deprecations? | no |
Tests pass? | yes |
Fixed tickets | #11073 |
License | MIT |
Doc PR | no |
You blindly trust the received headers here, whereas the previous version required the proxy to be configured as "trusted proxies". Should you configure your proxy as "trusted proxy"? see http://symfony.com/doc/current/components/http_foundation/trusting_proxies.html |
preg_match_all('{(for)=("?\[?)([a-z0-9\.:_\-/]*)}', $forwardedHeader, $matches); | ||
$clientIps = $matches[3]; | ||
} elseif ($this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) { | ||
$clientIps = array_map('trim', explode(',', $this->headers->get(self::$trustedHeaders[self::HEADER_CLIENT_IP]))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@alexandresalome Concerning your previous comment, I am still checking the trusted headers here. Or am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your first test is to verify if headers contains Forwarded, but you should only trust it if the IP is a Proxy IP.
ping @symfony/deciders |
array(array('127.0.0.1'), '127.0.0.1', 'for="_gazonk"', null), | ||
array(array('_gazonk'), '127.0.0.1', 'for="_gazonk"', array('127.0.0.1')), | ||
array(array('192.0.2.60'), '::1', 'for=192.0.2.60;proto=http;by=203.0.113.43', array('::1')), | ||
array(array('2620:0:1cfe:face:b00c::3', '192.0.2.43'), '::1', 'for=192.0.2.43, for=2620:0:1cfe:face:b00c::3', array('::1')), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth adding a test case for Forwarded: For="[2001:db8:cafe::17]:4711"
returning [2001:db8:cafe::17]:4711
. I don't think the current code handles it well. I also think it should preserve the [] for IPv6 as that is the common notation, but not sure if there are other precedents in symfony.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also worth adding a test for Forwarded: For="127.0.0.1:80"
which should return 127.0.0.1:80
(I think it does, but just for completeness' sake)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've checked and it does not handle the port as is. I'll make the necessary changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Seldaek I can't add a test for ips like [2001:db8:cafe::17]:4711
as it is later rejected by the IpUtils::checkIp
call. What do you suggest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tony-co [2001:db8:cafe::17]:4711
as header should return 2001:db8:cafe::17
for the IP, not [2001:db8:cafe::17]
, and it will be accepted. The square brackets are not part of the IP. They are only part of teh IP+port notation, because there are :
in the IP itself
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah sorry my initial comment was misleading I forgot that this method is called getClientIp while I was lost reading the spec :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ping @stof Ok I added the test for [2001:db8:cafe::17]:4711
. But still struggling with the 127.0.0.1:80
as the :
misled the IpUtils::checkIp
thinking this is an IPv6...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you should strip port numbers before passing them to checkIp, since this is just about getting the IP out it makes no sense to keep port info anyway.
Looks good to me apart from the ipv6 thing I commented on. 👍 when that gets resolved. |
Oh yeah another detail, there should be a doc ticket opened to at least change http://symfony.com/doc/master/cookbook/request/load_balancer_reverse_proxy.html#my-reverse-proxy-uses-non-standard-not-x-forwarded-headers to stop advertising X-Forwarded as standard IMO. |
@tony-co please reabse your PR |
if (!self::$trustedHeaders[self::HEADER_CLIENT_IP] || !$this->headers->has(self::$trustedHeaders[self::HEADER_CLIENT_IP])) { | ||
return array($ip); | ||
if (self::$trustedHeaders[self::HEADER_FORWARDED] && $this->headers->has(self::$trustedHeaders[self::HEADER_FORWARDED])) { | ||
$forwardedHeader = $this->headers->get('Forwarded'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should not use Forwarded
but self::$trustedHeaders[self::HEADER_FORWARDED]
here
82fbee7
to
24a309f
Compare
24a309f
to
b8ed555
Compare
b8ed555
to
dd1a560
Compare
@Seldaek A few weeks ago, Fabien merged a fix to strip the port. |
Looks good to me I think :) |
Thank you @tony-co. |