Problem/Motivation
Malformed HTTP Host headers can cause DOS vulnerabilities in Drupal because of the way multisite negotiation gets handled. The Host header needs to be validated to prevent this.
Proposed resolution
Now that #2278353: Update to Symfony 2.5 is done, we can refactor DrupalKernel to use Request::getHost() and friends. Request::getHost() does some of what we need. We also need to wrap this to add Drupal-specific from the D7 patch that is missing from Request::getHost().
Remaining tasks
- #2278353: Update to Symfony 2.5
Add a method to DrupalKernel with the additional host name checks.Call the new method before the multisite directories are searched.Throw an exception if the hostname does not validate.- Write tests.
User interface changes
None.
API changes
None.
Original report by @klausi
See https://www.drupal.org/SA-CORE-2014-003
The original patch against D7 is attached.
| Comment | File | Size | Author |
|---|---|---|---|
| #106 | interdiff-99-106.txt | 2.29 KB | mpdonadio |
| #106 | port_http_host_header-2304949-106.patch | 10.51 KB | mpdonadio |
| #99 | interdiff-96-99.txt | 3.38 KB | mpdonadio |
| #99 | port_http_host_header-2304949-99.patch | 10.08 KB | mpdonadio |
| #96 | interdiff-92-96.txt | 2.07 KB | mpdonadio |
Comments
Comment #1
klausiComment #2
klausiComment #3
longwavedrupal_valid_http_host() was removed in #2016629: Refactor bootstrap to better utilize the kernel and we no longer perform any validation, but DrupalKernel::findSitePath() looks very similar to D7's conf_path() so the vulnerability likely still exists.
Comment #4
catchLet's add back the validation from 7.x while we're here, looks like an oversight in the other issue.
Comment #5
cilefen commentedJust to kick this off, I am trying to figure out where this should go.
Comment #6
cilefen commentedComment removed for security reasons.
Comment #8
larowlanhttps://github.com/sensiolabs/symfony-httpfoundation-request-host/pull/2...
We will need to update our findSitePath to use getHost
Comment #9
larowlanhttps://security.drupal.org/node/124338
Comment #10
cilefen commentedSymfony had the same vulnerability that had to be patched before we could proceed with this issue. Symfony just released a patch. http://symfony.com/blog/cve-2014-5244-denial-of-service-with-a-malicious...
So we must postpone on #2234277: Composer update (includes security fixes) then figure out if anything else needs to be done on this.
Comment #11
cilefen commentedComment #12
catchTagging with D8 upgrade path, see issue summary of #2341575: [meta] Provide a beta to beta/rc upgrade path for why.
Comment #13
cilefen commented#2278353: Update to Symfony 2.5 is in so this is active.
Comment #14
cilefen commentedSee Symfony\Component\HttpFoundation\Request::getHost.
Comment #15
cilefen commentedJust to be thorough, HEAD is on Symfony 2.5.5 and here is the commit where the fix was added: https://github.com/symfony/symfony/commit/0aaabbfe8b49b436fe321823d89ae8...
Comment #16
cilefen commentedComment #17
cilefen commentedComment #18
cilefen commentedComment #19
larowlanDo you think we should bring in the tests too? Although note that we got them into Symfony upstream anyway.
Comment #20
cilefen commented@larowlan I am divided on that. If we were building Drupal from scratch right now and using the Symfony Request class, we would not write a test for this.
Comment #21
klausiSo now the method findSitePath() can throw \UnexpectedValueExceptions. Should we catch those or let them through? We should at least document them in the method docs with the current patch. I would suggest to catch it and return 'sites/default'?
Same here. In D7 we returned 400 Bad request response, are we doing that now? I think we should have a test case for that.
Comment #22
cilefen commentedComment #23
cilefen commented@klausi Thank you for the review. I think that if a request is this malformed, there should be no fallback.
Comment #24
klausiThis patch does not fix the DoS issue. I tested with the attached script.
Before the patch (D8 dev from today): 10 seconds response time with 100% CPU
With the patch from #23: 8 seconds with 100% CPU
Drupal 7: 0.006 seconds
So there is still a bug somewhere.
Comment #25
mpdonadio#23 doesn't take into account hosts running on ports other than 80. Patch attached, but still shows ~6sec requests w/ the @klausi script.
Setting to Needs Review just so tests run.
Comment #26
klausiMy gut feeling is that throwing the exception just triggers the theme system which then tries to make sense of the overlong, invalid HTTP host eating up lots of CPU cycles.
Drupal 7 simply stops execution in drupal_environment_initialize():
Comment #27
mpdonadioIf I just throw in
Then the DOS script runs in about ~170ms. Does this mean that the Symfony update isn't sufficient to protect against the DOS?
Comment #28
mpdonadio@klausi, if you change
to force the exception, your test script executes in about 150ms.
Comment #30
cilefen commented@klausi I am trying to do it by-the-book with that exception. It is interesting that it may not actually help.
This:
is preferred over
Comment #31
cilefen commented@mpdonadio: Could you try:
... at both places with the try/catch in DrupalKernel?
Comment #32
mpdonadioThe header() thing didn't seem to make any difference. We should profile this to see where the delay is coming from.
Comment #33
cilefen commentedComment #34
mpdonadioTwo more data point on this before profiling,
1. I wasn't totally accurate in #32.
does not result in the 400 Bad Request being generated. The output from the script is a 404 Not Found page where all of the URLs are using the spoofed HOST from the script.
2. The delay does not seem to depend on the length of the spoofed hostname. If I edit the DOS script above to make it a 10 char spoofed hostname, it still takes 6 seconds to run.
Comment #35
David_Rothstein commentedWouldn't the correct code actually be:
rather than:
?
(note the parentheses)
Comment #36
cilefen commented@David_Rothstein that's what happens when I code in comment boxes
Comment #37
larowlanWe're actively working to remove exit from core, can this be done without adding new calls?
Comment #38
berdirOk, so we figured out two things:
a) To be vulnerable to this in 8.x, you need a sites.php (it can be empty), as otherwise, we don't do the multisite check.
b) Symfony does *not* include the same validation spectrum as https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drup..., it does *not* validate the length or amounts of ./: in any way.
We can of course fix this just in Drupal, as the meaning of ./: is somewhat custom to Drupal/multisite behavior. But we should probably check with symfony just to be sure. There is no information on https://github.com/symfony/symfony/pull/11828 what exactly they are preventing from.
Comment #39
cilefen commentedhttps://github.com/symfony/symfony/issues/12349
Comment #40
cilefen commentedComment #41
cilefen commentedWe could handle this in Drupal with a forward-port of drupal_valid_http_host() to a method on DrupalKernel, and call it before getHost(). If anyone knows of a better way, speak up!
Comment #42
cilefen commented@larowlan, et al. We will try not to introduce another exit(). BadRequestHttpException does some more processing and that later results in a fatal because the hostname isn't found. It may be possible to create a custom Response instead. I am hoping that would end execution, in order to avoid the fatal.
Comment #43
mpdonadioBetter version of patch in #25 to account for HTTP running on something other than port 80, and HTTPS running on something other than port 443.
Comment #44
larowlanExceptions should not use t()
$request->getHttpHost() handles all of this logic for us.
Comment #45
mpdonadioThanks for the input. Used $request->getSchemeAndHttpHost() to simplify things more. Also added the @throw links to the docblocks.
Comment #46
cilefen commentedBecause, Request::getHost() does not check for the number of periods or colons in the hostname, Drupal is still vulnerable without some more validation. @Berdir and I agree that we need to add a method to DrupalKernel, something like the following. This is my idea for the method, which is based on drupal_valid_http_host() from D7, but without the preg_match, which is redundant to getHost(). We would want to throw an exception in this method or in the calling code if this method does not return TRUE:
Comment #47
mpdonadioI'm going to start work on this based on the patch in #45.
Comment #48
cilefen commented@mpdonadio: this is an effort handle it at a low level. Sorry, I know you are working on this but I thought about it all day.
Comment #49
cilefen commentedComment #51
berdirI don't think we even call drupal_bootstrap() anymore in the normal bootstrap?
I think it is OK if we do that check specifically before the multisite lookup, the DOS attack is specific do that, so it's OK to do the validation specific to that? Then we also don't have to call the validation method if there is no sites.php, as we don't really care about crazy hostnames then.
Comment #52
cilefen commented@Berdir - Thank you. More like this?
Comment #53
cilefen commentedI mean ... this
Comment #54
berdirYes, something like that I think. Now we need to figure out how to test this, web test won't work, maybe a unit test? But that won't work as long as findSitePath() calls functions like drupal_valid_test_ua().
Comment #55
cilefen commentedComment #56
klausiThis new method should always be called in some environment initialization method. That way we can make sure that such a malicious request is always aborted, regardless of multisite configuration or not. Drupal should just stop bootstrapping and throw a 400 bad request response. And then we can also reliably test this with a web test for example. This is also the way it is handled in Drupal 7.
I assume this is wrong because you do not include mpdonadio's changes regarding port numbers?
void? Nope, this is just boolean.
conf_path() does not exist in D8, you should point to ->findSitePath().
Comment #57
cilefen commented@klausi: Thank you for reviewing. This is just 3 and 4. @mpdonadio: Would you be kind enough to do 2?
Comment #58
cilefen commentedComment #59
klausiOh, I overlooked one of Berdir's previous comments. We should definitely not ignore crazy host names and always bail out early, so that there are no subsequent security issues with any code that makes use of the Host header.
Comment #60
mpdonadioOK, here is a first pass, but it is incomplete. There is a slight deviation from @cilefen and I discussed, but I think this is better.
There are two places we need to do the hostname checking, DrupalKernel::findSitePath (because of the multisite negotiation), and either ::preHandle or ::initializeRequestGlobals because the global $base_url gets set there, and getHost() gets called. I only modified the first.
We had originally thought about a new exception for the length problem, but that didn't make sense when I added the catch.
I attached three bash scripts. test1 has a long spoofed host, and will generate a proper 400 response. test2 has a spoofed Host under the character limit, and will generate a proper 200 (which is expected). test2 has an invalid spoofed host, and will generate a proper 400 response. For all three, you should have an empty sites/sites.php so the patch gets triggered.
Looking for input on two things.
1. Is this approach correct?
2. If so, is there a better way to generate the 400 that can avoid the exit.
If we think this approach is OK, then we need to figure out where to do the catch when there isn't a sites.php.
Setting Needs Review b/c I want to see the testbot output.
Comment #61
catchWhy not do the bail out directly in findSitePath() since that's where the DoS is?
For $base_url I think that's not relevant here given #2221699: HTTP_HOST header cannot be trusted was bumped to critical.
Comment #62
larowlanSo lower in this same function we call $response->prepare()->send() to redirect to install.php but don't call exit.
Is this different because it's not a redirect?
nitpick: missing new line between the }'s
Comment #63
mpdonadio@cilefen's latest patch w/ better handling for non-standard port numbers. interdiff-57-62.txt shows this.
interdiff-48-62.txt just shows what the differences to my approach are.
Comment #64
mpdonadio@larowlan, I assume #62 was looking at port_http_host_header-2304949-48.patch...
Yeah, the exit is there b/c without it Drupal went through the bootstrap process and rendered out a page, when all I wanted was a simple error code to go back to clients as this is an exceptional case. I see it an analogous to the fast 404 handling in Drupal 7. Is there a better way / place to catch this?
@catch, I assume #61 was to me, also. I did a try/catch in createFromRequest() instead of a direct abort from findSitePath() as it seemed the more better way to do it from a semantic perspective of initializing from a request object and getting that particular exception.
I am deferring to everyone else as to how to proceed here... And sorry for the confusion here; I must have had an old tab open and forgot to refresh when went to post my patch.
Comment #65
klausiThis comment gives a pretty good hint where we could do the sanitization. Let's keep the comment and move the validation there?
I can confirm that the patch fixes the DoS issue with the script I posted above. The response is HTTP/1.1 500 Internal Server Error, which is wrong, this should be 400 Bad request, because the server did nothing wrong.
And we need a test case.
Comment #66
mpdonadioWorking on this, starting from the patch in #63.
Comment #67
mpdonadioThis adds the check per @klausi above, and attempts to add an event subscriber to generate a proper 400 Bad Request.
The exception doesn't get caught. Testing with AccessDeniedHttpException and NotFoundHttpException don't work either, so I think I am missing a key concept for how the event subscribers work.
Advice / guidance appreciated.
Comment #68
znerol commentedSummary from discussion on IRC: It has been proposed to move the check into an early middleware. However, the container is initialized after the site path has been determined and therefore a check at this point in time is not effective.
It follows that the HTTP_HOST header needs to be validated before the container is initialized, and consequently a response needs to be generated without the help of any container services.
Comment #69
znerol commentedAlso note that Symfony
Request::getHost()throws anUnexpectedValueExceptionif validation fails. Therefore we probably should just do the same.Comment #70
mpdonadioHere is a temporary patch that will give us a starting point for making tests. It's mostly evil, but it will generate a 400 for bad Host headers. Just settings Needs Review for testbot.
Additional notes from IRC:
core/rebuild.php doesn't go through DrupalKernel::createFromRequest(), so the hostname validation may need to be moved back to DrupalKernel::findSitePath() (it is protected by default). We should also audit the entry paths to make sure there aren't any other exceptions.
One idea to do this properly is to do the check and return a NullKernel with an empty handle() method instead of using exceptions. The same thing could be done with the install redirect.
Comment #71
berdirThere is no way we can implement a reliable web test here?
a) this only works if you have a sites.php(Ok, if we do the validation earlier, then this is not needed, but there's still b)) and b) Only if you provide an invalid host name, which doesn't work for common vhost setups?Comment #72
cilefen commentedComment #73
mpdonadioComment #74
gaurav.goyal commentedPatch rerolled.
Comment #75
gaurav.goyal commentedComment #76
mpdonadioI messed something up in #70 (I think I generated the patch w/o rebasing first). I am going to reroll starting from #67, possibly with two or more ideas about how to proceed.
I had thoughts about testing, but can't remember what they were. Maybe they will come back to me as I work on this...
Comment #77
mpdonadioSomewhere between port_http_host_header-2304949-62.patch and now, I think I missed a rebase when I generated a patch, and some extra code got in. The attached fixes this.
I think this is our best (least bad?) approach.
It generates a quick 400 with my test scripts, and it will do the detection for both multisite and normal.
The check is done in DrupalKernel.php::findSitePath() as that is the entry point from rebuild.php, should someone accidentally expose this. Otherwise, I think directly after the static::bootEnvironment(); in DrupalKernel.php::createFromRequest() would be more logical place.
The check throws BadRequestHttpException(), which is the Symfony 400, but index.php and rebuild.php catches HttpException. This should future proof things in case Symfony barfs before we have a kernel in place.
My questions are
-- Do we want this protection in rebuild.php? If not, I think moving the code to DrupalKernel.php::createFromRequest() is better.
-- Do we want this protection in authorize.php also? If so, we need the logic there.
-- Any ideas on if this is actually testable?
Comment #78
mpdonadioApparently, I forgot to change the status...
Comment #79
cilefen commentedWe could consider making a pull request for this.
Comment #80
dawehnerI wonder whether we should move this code a little bit down, so that this validation check is done directly before using the host ... its a bit odd to have that before the simpletest check.
<3 but a little bit out of scope?
I think you should do rather create a response object and call $response->send() instead
Comment #81
znerol commentedRe #77
Regarding whether or not
rebuild.phpshould be protected or not, it was argued in IRC that this script should not be accessible in production anyway (because that would lead to all sorts of DoS opportunities). The rebuild script can be disabled by adding$settings['rebuild_access'] = FALSE;tosettings.php. However, note that before being able to read settings, the rebuild script needs to invokeDrupalKernel::findSitePath()- a classic chicken-egg problem. Therefore it is necessary to protectrebuild.php.Also note that
findSitePath()is always called - even for sites which do not use the multisite functionality. It is the only way to actually find the propersettings.php. Therefore the concerns expressed againstfindSitePath()are moot IMHO (it seems to me that #56 is not so well-informed in this regard). Keeping it there will automatically protectauthorize.php,rebuild.phpand will work for virtually any crazy way to set up a workingDrupalKernel.Instead of putting the whole logic into
findSitePath()it might be feasible to extract it to apublic static validateRequest(Request $request)method inDrupalKernel[Interface]and then just invoke that method from withinfindSitePath(). This might also make it possible to cover that method with a unit-test, because it resolves the problem pointed out by #54 (i.e. a unit test simply could testvalidateRequest()instead of the wholefindSitePath()method.getHost()always returns the hostname without the port number, thus remove the code which strips some lines further down.Re #80
I don't think so. This comes from #23. In my understanding
HTTP_HOSTshould not be accessed directly anywhere throughout our codebase. This patch removes all occurrences from production code.Comment #82
mpdonadioOK, another patch...
#80.1: If this code is being called on every request don't we want to make sure it is also called for every simpletest request? That is why I put it at the top.
#80.2: As mentioned above, #23 made the change to not access HTTP_HOST directly. This change was introduced in #25 because the code below it needs the port number.
#80.3: I put this in. It may be overkill, but calling ->prepare() since we are returning a 4xx code may not be a bad idea.
#81.1: I made a public validateRequest() that returns a boolean. Added tests to DrupalKernelTest that i think cover all the bases, and they pass locally for me. Left the throw BadRequestHttpException in findSitePath().
#81.2: Removed port logic for from the cookie setup code.
Comment on validateHostnameLength(). This was based on the Drupal 7's drupal_valid_http_host(). These limits could possibly be tightened up per RFC1035, which says 255 octets for a hostname (that count includes the implicit trailing dot), and we may not need the colon detection since ->getHost doesn't seem to include that?
Comment #83
mpdonadioIt would help to attach the files...
Comment #85
znerol commentedUse
static::instead ofself::. See docs on late static binding.Use the same comparison operators in both places.
The message of the exception is never used, therefore it is not very useful to set it here.
Do not mention that RFC here, it is outdated. In fact we add the leading dot in order to maximize browser-compatibility, see #2347877-17: Move DrupalKernel::initializeCookieGlobals() into a SessionConfiguration service. If in doubt do not add the comment in order to prevent bike-shedding about that.
I tend to think that this could be inlined into the new
validHostnamefunction. On the other hand I also see the value in keeping it analogous to the D7 function. Other opinions?Use
static.That does not seem to be used.
Great that this is finally testable. Note that it might be worthwhile to keep the test-scenarios inline with the ones from D7 in order to simplify maintenance. See BootstrapIPAddressTestCase::testIPAddressHost().
In the D7 version, the response has no body (i.e. there is no print in the respective part of drupal_environment_initialize(). Just use
$response = new Response('', $e->getStatusCode());.Comment #86
mpdonadioI think keeping validateHostnameLength() as a separate function makes the code read better, especially with the try/catch logic that is needed in validateHostname.
And before I post another version of the patch, keeping the validation in DrupalKernel::findSitePath() will protect index.php, rebuild.php, and authorize.php (our only entry points other than install.php, which doesn't need protection). We didn't fully decide whether we need to generate a 400 in rebuild.php and authorize.php. Do we need/want to generate a 400 from these when validation fails? The change would be similar to the attached.
Comment #87
klausiwhy isn't this a phpunit test if you are only testing the validateHostname() method? It would be nice to have test coverage for the added code in at least index.php by writing a web test that issues a malicious request with an invalid host name, but would be a bit tricky to implement since I think you cannot use cURL and would have to fiddle with PHP sockets yourself.
I would have liked to see a more generic request validation phase in the DrupalKernel, since we will most likely encounter further security issues on the request object during the D8 release cycle. It feels a bit hacky to just always tuck them onto the place where we find vulnerabilities. But for the sake of making progress here let's go with this approach and postpone that.
Otherwise looks good to me, please fix the test to use phpunit (or add a comment why you can't) and implement znerol's feedback, which looks valid to me.
Comment #88
mpdonadioOK, all of the feedback from #85 is done, but I left validateHostnameLength() as a separate function as I think this make the code read better.
Added try/catch logic to rebuild.php and authenticate.php so a 400 will be generated. I can back this out if desired.
Reverted core/modules/system/src/Tests/DrupalKernel/DrupalKernelTest back to HEAD
Created \Drupal\Tests\Core\DrupalKernel\ValidateHostnameTest. Didn't see a better place to put unit tests for DrupalKernel. Mirrors the D7 version.
Tomorrow I'll make a followup issue about a generic request validation phase, and try to summarize it.
Comment #89
berdir@klausi: A web test is impossible here, for the simple reason as that will never work in a vhost environment as you never get to the right vhost, AFAIK.
Comment #90
mpdonadioFrom Name-based Virtual Host Support:
So, when we spoof the Host header in the test, we may never arrive at the proper virtual host. The only situation where this may work is if qa.drupal.org doesn't do name-based virtual hosting, but that would really complicate people running tests themselves and I have never seen a reliable way to detect from PHP whether name-based virtual hosting is actually being used.
Comment #91
klausiI see, so a web test is out of the question. I guess testing DrupalKernel::createFromRequest() is also impossible because it is tied to global state much ... so the pure unit test seems to be all that we can do.
needs to be fully namespaced. Should have a description like "In case the host name in the request is invalid."
"!== TRUE" is harder to read than simply "=== FALSE".
the Request class needs to be fully namespaced in the comment.
same here with the "=== FALSE"
you can just return FALSE here and move that check out of the try/catch block?
you don't need to create the request from globals. Just use the constructor of the request class. Then you also don't need to mess around with $_SERVER.
Almost ready otherwise, good work!
Comment #92
mpdonadioThis should address #92:1-6
Comment #93
znerol commentedWhile manual testing I noted that the exception is not caught here. This is due to a missing use-statement. Same for
rebuild.php. Also note that there isHttpExceptionInterface, I suggest type-hinting against that.I tried to reproduce the results with the script from #24 for the following paths:
Note that
statistics.phpandinstall.phpdeliver a zero-length (no body) page with status code 500. I think this is okay.Regrettably I do not see much of a difference between a proper request and a forged one for HEAD. I guess that's probably because I use an SSD. So maybe somebody with a good old hard-disk could run the test script against the new patch and post the results?
Comment #94
klausi@znerol: Are you missing the multi site configuration file mentioned in #38 to exploit the DoS?
Comment #95
znerol commented@klausi indeed.
I've slightly adapted the test-script and inserted a call to
wgetfor each URL in order to have a baseline. The patch provides an effective protection for all front-controller scripts. Note the simpletest mock-frontcontrollers (http.phpandhttps.php) are already protected by the call todrupal_valid_test_ua()inTestKernel::createFromRequest().Attached is the modified dos script as well as the output produced by running it on my machine.
So, this is ready except for the missing
usestatements and the usage ofHttpExceptionInterfaceinstead ofHttpExceptionin the catch clauses (#93).Comment #96
mpdonadioReplaced HttpException with HttpExceptionInterface.
There was a small conflict when I rebased this morning; interdiff is between my git branches after the manual conflict resolution.
Comment #97
klausiLooks good to me now, thanks!
Comment #98
Crell commentedThis should be done with a @dataProvider, no?
Comment #99
mpdonadio@timplunkett pretty much did this quicker than me when I asked about DataProviders in IRC. The patch is essentially his. He also added the coverage for returning TRUE, I added in the IPv6 loopback test from BootstrapIPAddressTestCase.
Setting Needs Review so TestBot runs this immediately.
Comment #100
dawehneryou could also just do a
return static::validateHostnameLength($http_host)and be done with itAre we 100% sure that we don't want to use $e->getMessage()?
Comment #101
mpdonadio#100-1, I left it that was for a cleaner patch for when/if Synfony handles the hostname length internally. I change this if desired.
#100-2, in #88 we removed the exception message, which may or may not line up with the status code we are sending back.
This would just probably be better if we want content.
Comment #102
znerol commentedWe do not want to emit a body because if we did we'd need to take extra-care with escaping it and whatnot. The status text (Bad request) is already in the status header.
Comment #103
alexpottThis test is not testing what you think it is.
Throws an invalid value exception. Something like
['HTTP_HOST' => str_repeat('a.', 101)];is what you want.Comment #104
mpdonadioPer some IRC with @klausi and @alexpott, I am going to rework the tests to diverge from the exact test cases from drupal_valid_http_host() in the Drupal 7 BootstrapIPAddressTestCase::testIPAddressHost, and to the cover the Drupal 8 cases better.
There are two parts of this. One are the bad hostname lengths that we check for in DrupalKernel::validateHostnameLength (which are the real cause of our DOS issues). The others are the exceptions that Request::getHost() will throw.
We are currently testing for one case, which are characters outside of what is defined by RFC 952/2181.
We are not testing the trusted hosts mechanism that the class defines. AFAIK, we don't support this in 8.0.x, but we may want to in the future. Should I add test coverage for these too, while I am at it?
Comment #105
klausiNo, I think we should only fix the security issue here.
Comment #106
mpdonadioAdjusted tests based on some IRC w/ @klausi and @alexpott.
-- Updated comment to match what Request->getHost() checks for (which is the exception that gets caught in ::validateHostname()
-- Updated the second batch of tests to better reflect real hostnames that we consider invalid in ::validateHostnameLength()
-- Added two tests for valid IPv4 and IPv6 hostnames to make sure they OK with these two methods.
Comment #107
klausiUpdated test cases look good.
Comment #108
alexpottThis issue addresses a critical bug and is allowed per https://www.drupal.org/core/beta-changes. Committed 62ee12b and pushed to 8.0.x. Thanks!
Comment #111
donquixote commentedPhpStorm now rightfully complains:
The variable 'request' might have not been defined.
The IDE is always right.
What to do?
Comment #112
donquixote commentedWe could fix it like this:
It an exception is thrown in Request::createFromGlobals(), we will not catch it. Is this ok?
Maybe Request::createFromGlobals() never throws HttpExceptionInterface kind of exceptions. But it is always nicer to have IDE-proof logic.
Comment #113
znerol commented@donquixote: Please bring that up in #2389811: Move all the logic out of index.php (again).
Comment #114
mpdonadioCleaning up the issues that I am assigned to...
Comment #115
jibranThis has been closed now. How can we remove this @todo now?
Comment #116
mpdonadio#2533218: Resolve todo for Symfony #12349 created.