Inconsistent handling of Content-Disposition header starting with a semicolon
Reported by
t...@adblockplus.org,
Feb 28 2017
|
||||||||||
Issue descriptionUserAgent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.12; rv:50.0) Gecko/20100101 Firefox/50.0 Bugcrowd/1.0 Example URL: http://chrome-navigation-tester.kzar.co.uk/ Steps to reproduce the problem: 1. Go to http://chrome-navigation-tester.kzar.co.uk/ 2. Enter ";foo" for "Content-disposition header" (without quotation marks). Other values to test are ";;;;;attachment", ";inline" or ";foo?" 3. Click Submit and watch Chrome handle the server response containing this Content-Disposition header. What is the expected behavior? With an RFC 2183 compliant parser, all values listed in step 2 have an empty disposition type. So all of them should be treated like "Content-Disposition: inline" and the browser should navigate to the result page. This is the behavior I see in Firefox 51 for example. What went wrong? In Chrome (versions 55, 56 and 58 tested) only "Content-Disposition: ;inline" and "Content-Disposition: ;foo?" result in navigation, other values listed cause the request to be ignored entirely - it shows up in Developer Tools but doesn't even trigger a download. Did this work before? N/A Chrome version: 55.0.2883.87 Channel: stable OS Version: Ubuntu 16.10 (64-bit) Flash Version: The handling of Content-Disposition header seems to be inconsistent internally. For purposes of downloads (function MimeSniffingResourceHandler::MustDownload()) the header is treated correctly which is why none of these headers trigger a download. The handling for purposes of navigation ignores leading semicolons however so that "Content-Disposition: ;foo" is considered equivalent to "Content-Disposition: foo" and doesn't result in navigation (unrecognized disposition types are treated like "attachment"). This is also why "Content-Disposition: ;inline" and "Content-Disposition: ;foo?" still result in navigation, the former because disposition type is considered to be "inline" and the latter because "foo?" isn't a valid HTTP token so it is rejected as disposition type.
,
Feb 28 2017
Well yes you should see the "letsgo" page if navigation occurred (without a redirection.)
,
Feb 28 2017
Alright. Am a newbie to Chromium and I'd like to check debug this issue :).
,
Mar 2 2017
mmenke, rdsmith, rsleevi: Can one of you take a look?
,
Mar 2 2017
Adding in Asanka as well, since I suspect he's familiar with C-D from the downloads work.
,
Mar 2 2017
I'm going to go ahead and WontFix this - the report both misunderstandings how Content-Dispositions work, and the spec. First off, per RFC 2183, the value before the first semi-colon in the content-disposition line is disposition-type, everything after that is a disposition-parm. (Note that this is indicated by the use of semi-colon. HTTP headers with lists of the same type of objects generally use a comma separator. Ones where the first value is the main value, and the others are parameters generally use semi-colons). Secondly, per the RFC, unrecognized content-disposition types should be treated as attachment, not inline (See section 2.8 of the RFC), and the empty string is not a recognized content-disposition.
,
Mar 2 2017
,
Mar 3 2017
Friendly reminder: reading bug description before replying helps. I am reporting bogus handling of invalid Content-Disposition headers, namely those starting with one or multiple semicolons. The disposition type is empty in this case which should result in it being treated like inline - it's not an unknown disposition type but rather a missing one. You can look up that logic in HttpContentDisposition::ConsumeDispositionType() in the Chromium code base, and that's how such responses are being treated by Firefox. However, it seems that there is a second code path within Chromium that I wasn't able to find yet, one that ignores leading semicolons. This second code path causes the strange behavior described in this report. And I am pretty sure that ignoring leading semicolons isn't in line with the RFC. For reference, we discovered that bug when we tried to "predict" in Adblock Plus whether a particular HTTP response will result in navigation.
,
Mar 10 2017
Re-opening this, per above comment (Sorry, put this on my todo list, but never got back to thinking about it).
,
Mar 15 2017
I tried to ignore the leading semicolons and it works fine and we get the same behavior as we see in firefox or IE
,
Mar 15 2017
Hey, Charles, can I take advantage of your blink expertise? After a bit of source code digging, I spun up a local instance of Chrome and tried to track what happened in ResourceLoader, and it looks like it is successfully completing a GET to "http://chrome-navigation-tester.kzar.co.uk/letsgo/0.338618?statuscode=200&content-type=&location=&content-disposition=%3Bfoo" and handing that over to the AsyncResourceHandler. Which I think means the problem is further up the loader stack. Do you know if/where in blink the Content-Disposition header is evaluated?
,
Mar 15 2017
https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/network/HTTPParsers.cpp?rcl=aaf85a1175da26db6baac2735e5d64271c5c8f17&l=270 HTTPParsers maybe is what you're looking for?
,
Mar 16 2017
Exactly, this looks like the other Content-Disposition parser I was looking for. The logic is similar to HttpContentDisposition but not identical. From what I understand, the problematic line is this one:
contentDisposition.split(';', parameters);
This implicitly sets allowEmptyEntries parameter to false, so the split will ignore empty strings. Changing it to contentDisposition.split(';', true, parameters) should fix the issue reported here. From the look of it, otherwise the result should be identical to HttpContentDisposition.
,
Mar 16 2017
Thanks for taking a look trev. To Blink>Loader for assignment, and cc tyoshino, is this in your wheelhouse?
,
Mar 16 2017
Should we use the same code in net/ and blink/ to parse the header, now that we can?
,
Mar 16 2017
Removing network label, as it seems this is a blink issue.
,
Apr 28 2017
,
Apr 28 2017
> #8 > The disposition type is empty in this case which should result in it being treated like inline Sorry, can you tell me where it is specified? I skimmed RFC 2183, but failed to find the description.
,
Apr 28 2017
That's the logic I saw in both Chrome and Firefox code, but I didn't see this case mentioned explicitly in RFC. I guess the idea is that an empty disposition type is the same as no disposition type - meaning that the default behavior applies.
,
Apr 28 2017
Thanks, hopefully https://codereview.chromium.org/2844353003/ will fix the issue.
,
Apr 28 2017
The following revision refers to this bug: https://chromium.googlesource.com/chromium/src.git/+/a397826c00c0873475842d7f9d9d03038015dcdf commit a397826c00c0873475842d7f9d9d03038015dcdf Author: yhirano <yhirano@chromium.org> Date: Fri Apr 28 13:30:46 2017 Use net::HttpContentTypeDisposition in blink This CL replaces blink::GetContentDispositionType implementation by net::HttpContentTypeDisposition. There are some behavior differences between these two implementations, but because the former is used only to see if the disposition type is attachement, there is only one difference that matters. The former returns kAttachement for empty content disposition type (e.g., ";foo"), but the latter returns kInline. It looks the former is intended to return kNone, but it returns kAttachment due to misuse of confusing WTFString::Split interface. Hence this CL adds IsContentDispositionAttachment and makes it return false when a value with an empty content disposition type is given. BUG= 696967 Review-Url: https://codereview.chromium.org/2844353003 Cr-Commit-Position: refs/heads/master@{#467977} [add] https://crrev.com/a397826c00c0873475842d7f9d9d03038015dcdf/third_party/WebKit/LayoutTests/http/tests/loading/empty-content-disposition-type.html [add] https://crrev.com/a397826c00c0873475842d7f9d9d03038015dcdf/third_party/WebKit/LayoutTests/http/tests/loading/resources/empty-content-disposition-type.php [modify] https://crrev.com/a397826c00c0873475842d7f9d9d03038015dcdf/third_party/WebKit/Source/core/loader/DocumentLoader.cpp [modify] https://crrev.com/a397826c00c0873475842d7f9d9d03038015dcdf/third_party/WebKit/Source/platform/network/HTTPParsers.cpp [modify] https://crrev.com/a397826c00c0873475842d7f9d9d03038015dcdf/third_party/WebKit/Source/platform/network/HTTPParsers.h
,
May 1 2017
|
||||||||||
►
Sign in to add a comment |
||||||||||
Comment 1 by nrav...@samsung.com
, Feb 28 2017