-
-
Notifications
You must be signed in to change notification settings - Fork 9.4k
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
[2.7] [HttpFoundation] [Request] Added check for valid host size limit #13522
Conversation
Don't you think that this should be done by PHP directly instead? |
Yeah, it would be great; but I don't know how PHP is handling this internally given the ticket #12349. Have you some hint @fabpot? |
What kind effect would this have with (for example) Arabic or Chinese characters? |
Well, after doing the tests in the way that @mpdonadio exposed in #12349 I get the conclussion that PHP isn't taking care about this RFC. I was thinking that Drupal was overriding or manipulating in some way the $_SERVER's content; but simply sending a long host header is enough to reproduce this issue. I've even tested it against |
@phansys I think this should be reported to PHP itself and fixed there. |
unfortunately it's not so easy. IDN are translated to ascii chars (for instance The length of |
OK @fabpot, I'll open a ticket in PHP in order to ask this feature. |
I've added support for that in PHP's filter extension some times ago: php/php-src#826 IDN domain names are not currently supported unless calling |
throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host)); | ||
if ($host) { | ||
if ('' !== preg_replace('/(?:^\[)?[a-zA-Z0-9-:\]_]+\.?/', '', $host) || | ||
0 !== preg_match('/(?:^\[)?[a-zA-Z0-9-:\.\]_]{256,}|[a-zA-Z0-9-:\]_]{64,}\.?/', idn_to_ascii($host)) |
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.
idn_to_ascii()
is only available if the INTL extension is enabled and this is not always the case.
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.
You're right @dunglas, thank you. I'm updating the tests and this logic in order to check if idn_to_ascii()
returns false (while invalid IDNs). Later I'll check filter_var()
with FILTER_VALIDATE_URL
based in your PR.
IDN are not an issue here because they must be sent encoded in punycode by the client in the Actually, a lot of invalid hosts will be considered valid including but not limited to:
I think it's not the responsibility of the $filtered = filter_var($host, FILTER_VALIDATE_URL);
if (!$filtered || $filtered !== parse_url('http://'.$host, PHP_URL_HOST)) {
// throw the exception
} |
Well said @dunglas.
When host is an IDN and
|
IMO this method should just blindly forward the host sent by the client, without any kind of validation. Not sure if removing an exception is considered BC but anyway this can be done for 3.0. For 2.7, if we really want a better validation (we must be careful about performance and DOS attacks vector) IDNs aren't an issue here because, As said in my previous message, the client (the browser) must sent the host encoded in punycode. |
@dunglas I've written some code to validate the hostname before, for domain forwards actually. What I did, was actually the On a side note, this is validation. This sort of seems to me like it could be part of a DNS or Domain name related (validation) component. #10467 |
My concern respect to BC is that if this check surpluses, it can be removed in 3.0 (in 2.7 someone can be relying on it as side effect). For the meantime, we could then trust in the header sent by the browser through In respect to validation component, it would be great to use it here or where needed; but note the About where to put this validation until PHP take the responsibility, I think it must be done at population time, not while trying to get the value. Based on @fabpot's comments about delegating this issue to PHP, I can't imagine (from a user point of view) other way than PHP validating it at moment of populating the |
IMO the responsibility of My suggestion: leave this code as is in 2.x (no change, no BC break), drop it in 3.0. |
Added check for valid host according to RFC 1035 - 2.3.4 (ticket symfony#12349): http://www.ietf.org/rfc/rfc1035.txt * 63 bytes limit for each domain label * 255 bytes limit for whole domain name | Q | A | ------------- | --- | Bug fix? | no | New feature? | yes | BC breaks? | kinda | Deprecations? | no | Tests pass? | yes | Fixed tickets | symfony#12349 | License | MIT | Doc PR | none Updated tests.
* Removed uppercased patterns since $host has already applied strtolower(). * Narrowed quantifiers to only match one char for invalid sizes.
throw new \UnexpectedValueException(sprintf('Invalid Host "%s"', $host)); | ||
if ($host) { | ||
if ('' !== preg_replace('/(?:^\[)?[a-z0-9-:\]_]+\.?/', '', $host) || | ||
0 !== preg_match('/(?:^\[)?[a-z0-9-:\.\]_]{256,257}|[a-z0-9-:\]_]{64,65}\.?/', $host) |
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.
would this be robust against the DoS attack mentionned in the comment ?
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.
Thank you @stof, I updated these lines and added a test for this case.
…tacks. * Added test to check timing while DoS attack.
…own from 1000 to 500 calls/sec).
Travis failures are not related to this feature (Symfony\Component\Process\Tests\SigchildDisabledProcessTest and Symfony\Component\Process\Tests\SigchildEnabledProcessTest). |
Closing, this piece of code does not try to validate the host, just to avoid having illegal characters in there. |
Added check for valid host size limit according to RFC 1035 - 2.3.4 (ticket #12349):
http://www.ietf.org/rfc/rfc1035.txt
TODO:
Replace preg_match() by preg_replace().(after a timing benchmark I foundpreg_match()
faster thanpreg_replace()
, but I also have made some little improvements in regexs).