When there is an uncaught exception, Drupal 8 displays a simple dump of the exception.
Although the page is served as 'Content-Type' = 'text/plain', it contains HTML. It looks better to me when I change the code (in FinalExceptionSubscriber.php
) to serve as 'text/html'. See attached images.
Setting to "Minor" as the message would never be shown in production. Nevertheless, when debugging it's tedious to try to read text that contains HTML tags.
I asked for help on Drupal Answers. @4k4 suggested that the problem was potentially related to #2853300: Standardize fatal error/exception handling: backtrace for all formats, not just HTML, and that the "obvious" fix of changing the content-type would revert that issue.
Comment | File | Size | Author |
---|---|---|---|
#17 | exception-html.2924850-17.patch | 2.4 KB | Keenegan |
#9 | exception-html.2924860-9.patch | 967 bytes | Keenegan |
#2 | exception-html.2924860-2.patch | 846 bytes | AdamPS |
ExceptionHtml.png | 70.74 KB | AdamPS | |
ExceptionText.png | 72 KB | AdamPS |
Comments
Comment #2
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedThis is the patch for the "obvious fix" that we probably don't want to apply. However it will be useful to see if this breaks any tests.
Comment #7
MurzThanks for the patch, it's short and works well for fixing described problem! Why it is obvious fix and not right? Does it broke some other places?
Comment #8
AdamPS CreditAttribution: AdamPS at AlbanyWeb commented@Murz well there are 274 broken tests:-)
I think the error should only be text/html if the original request was HTML. It needs to be 'text/plain' for JSON and similar. So the code should probably should be something like this:
It's not my top priority to create a new patch here, but if you are willing to create a new patch then I will definitely review it.
Comment #9
KeeneganHere is the patch based on #8
Comment #11
KeeneganOnly one fail now, but I think the test testBacktraceEscaping should change because of these two lines :
Comment #12
AdamPS CreditAttribution: AdamPS at AlbanyWeb commented@Kng thanks for working on this issue. Yes I agree - and as a bonus that means this patch will then have a test so no need to write a new one.
Comment #13
KeeneganOk, so I just have to change the test in my patch ?
Here's the patch with the ExceptionHandlingTest.php fixed
Comment #14
KeeneganComment #16
AdamPS CreditAttribution: AdamPS at AlbanyWeb commented@Kng yes you are going in the right direction. You might have to change the tests a bit more. Obviously each time we should verify that the original request in the test was HTML.
Comment #17
KeeneganOh yeah, I forgot about the testExceptionEscaping method.
This should be better now
Comment #18
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedLooks good thanks @Kng
Comment #19
KeeneganThank you for the huge help @AdamPS
Comment #21
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedTest fail was random, unrelated.
Comment #22
alexpottAn alternate fix and one that keeps the page text plain is to change the
<br>
tags to"\n\n"
. HTML in the exception message is already escaped so this is the only HTML on the page. I prefer this fix because in a way text/plain is defence in depth if auto-escaping the exception messages breaks for some reason.Comment #23
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedThanks @alexpott for looking at this issue.
I don't follow you. Yes exactly, the exception message is HTML-escaped which means it looks right in 'text/html' and wrong in 'text/plain'. Furthermore the exception message contains various HTML tags. Please see the attached image of this issue.
Given that this page calls
$message = new FormattableMarkup
it clearly does return HTML. Setting the content type to 'text/html' does seem like the right fix.The suggested fix to use
"\n\n"
does not solve the issue. Setting back to RTBC for maintainer response.Please can you outline a specific scenario? If the output is malformed in an edge case then it's not necessarily a problem - the output has been malformed in all cases for years now. Do you see a security risk somehow?
Comment #24
alexpott@AdamPS hmmm good point. I think my fear about not escaping exception messages is irrational. The message is constructed one of two ways
$message = new FormattableMarkup('%type: @message in %function (line %line of %file).', $error);
or
$message = new FormattableMarkup('%type: @message in %function (line %line of %file). <pre class="backtrace">@backtrace</pre>', $error);
In both instances there's nothing from $error that is not escaped and if FormattableMarkup we have bigger problems. Plus escaping on exceptions is tested in \Drupal\KernelTests\Core\Routing\ExceptionHandlingTest::testExceptionEscaping and \Drupal\KernelTests\Core\Routing\ExceptionHandlingTest::testBacktraceEscaping so that's good.
I've pondered if we should consider running
$content
through\Drupal\Component\Render\PlainTextOutput::renderFromHtml()
when outputting text/plain but that runs the risk of unescaping things so let's not to that here.Even though this is a bug fix I'm going to commit to 8.8.x just in case any of my assumptions about security prove incorrect. I'm very sure that there's no harm in making this change but as a minor fix there's no rush either.
Committed c7bfe49 and pushed to 8.8.x. Thanks!
Comment #26
AdamPS CreditAttribution: AdamPS at AlbanyWeb commentedGreat thanks @alexpott. I agree there is no rush, 8.8 is good.