fetch icon indicating copy to clipboard operation
fetch copied to clipboard

Add example(s) for X-Content-Type-Options

Open wolfbeast opened this issue 8 years ago • 13 comments

[See https://github.com/whatwg/fetch/issues/636#issuecomment-346558085 about adding examples. Below is the old purpose of this issue.]


https://fetch.spec.whatwg.org/commit-snapshots/860ab8669fb3775b77b6f81e44e5a2609db0bc93/#should-response-to-request-be-blocked-due-to-nosniff?

3.3.1. Should response to request be blocked due to nosniff? Run these steps:​ 1. If response’s header list does not contain `X-Content-Type-Options`, then return allowed. 2. Let nosniff be the result of extracting header values from the first header whose name is a byte-case-insensitive match for `X-Content-Type-Options` in response’s header list. 3. If nosniff is failure, then return allowed. 4. Let mimeType be the result of extracting a MIME type from response’s header list. 5. Let destination be request’s destination. 6. If destination is script-like and mimeType (ignoring parameters) is not a JavaScript MIME type, then return blocked. 7. If destination is "style" and mimeType (ignoring parameters) is not `text/css`, then return blocked. 8. Return allowed.

Many websites will use a blanket "nosniff" option because it's being pushed as a recommended security measure. However, many sites also do not supply a content-type header with every document/response returned. As a result, any script or style that would not have a supplied content-type in the header would, according to this spec, be blocked. Blocking should only occur on a mis-match of MIME type in the intention of this spec as I understood, and not when the MIME type is missing altogether. Since you can't compare between two values when one of them is missing, it should be allowed.

I suggest adding an additional step between 4 and 6: If mimeType is empty, then return allowed.

wolfbeast avatar Nov 22 '17 08:11 wolfbeast

The intention is very much a strict match. If the script or style sheet would still execute without a Content-Type header I'm not sure it would do much good protecting resources.

Are implementations inconsistent in this?

annevk avatar Nov 22 '17 15:11 annevk

Yes, implementations differ between browsers.

JustOff avatar Nov 22 '17 15:11 JustOff

Thanks, seems like Chrome never fixed http://w3c-test.org/fetch/nosniff/stylesheet.html. @mikewest what's up with that?

And I guess I should file some bugs on Edge tomorrow unless someone else wants to volunteer (fetch/nosniff/script.html has the test they most likely fail in addition to the one above).

annevk avatar Nov 22 '17 15:11 annevk

So, the intention is to block then? Works for me as well, as long as the spec is clear about it (which it currently is not, unless you want to consider "" a valid MIME type that should be matched...).

wolfbeast avatar Nov 22 '17 16:11 wolfbeast

It is clear I think. The empty byte sequence is neither a match for a JavaScript MIME type or text/css. There's no reference to "valid MIME type" in the Fetch Standard so I'm not sure what you mean by that.

annevk avatar Nov 22 '17 17:11 annevk

I mean that you can't really compare 2 values when one doesn't exist; see my original post on this issue above. How can you have a mis-match (which is what I read the intention of this header to be about) when you can't match 2 items because one isn't there?

It's neither a match nor a mis-match if the MIME type of the content is unknown.

If no content-type is specified, the way you can determine what the content is is either through assuming by file name/extension, or through sniffing. Even if sniffing isn't allowed, a client can still assume the content type based on the file name - in your interpretation, even that should be blocked while, strictly speaking, no sniffing is involved.

In addition: The way this is intended by you (strict check, even including an empty string as a match value), as a consequence, enforces always having a content-type specified; that's also not in the spec but a very real effect of interpreting the XCTO header that way.

As you can see there's a few things that aren't clear at all. Adding a statement that a MIME type must always be specified if the XCTO:nosniff header is sent in the response (and blocking otherwise) would make it unambiguous what the intended matching/blocking behavior is.

wolfbeast avatar Nov 23 '17 05:11 wolfbeast

File name is never consulted over HTTP. What makes you think it is? And yeah, for XCTO to work you always need a Content-Type header for script and style sheets. This follows directly from the algorithms in the specification.

annevk avatar Nov 23 '17 06:11 annevk

Maybe you're tripping over semantics here. with "file name" I meant the extension visible in a URL -- and it was an example indicating that apart from sniffing, a client can determine/guess the content type in other ways when not being specified with a header.

I'm not going to spend much more time on this issue, though, I have better things to do -- My point remains that the spec could be clarified and made completely unambiguous with a one-line change. Ultimately, it's the editor's choice to do or not do this.

wolfbeast avatar Nov 23 '17 07:11 wolfbeast

No, extensions are never used over the network. There's no standard that says they should be used either. Sniffing is defined in https://mimesniff.spec.whatwg.org/ and only used when invoked. It's not invoked here.

I still don't think there's any ambiguity here.

annevk avatar Nov 23 '17 08:11 annevk

I agree there's no ambiguity here. However, adding more examples to specs is often a good idea, and this issue points to a potential place to insert one. I'm skeptical that there will be that many other people who aren't used to the concept of the empty string/byte sequence and comparing it with other strings/byte sequences, but XCTO is still an interesting area of the spec worth adding examples for, even if it's just for web developers skimming the algorithms.

domenic avatar Nov 23 '17 08:11 domenic

Thanks, seems like Chrome never fixed http://w3c-test.org/fetch/nosniff/stylesheet.html. @mikewest what's up with that?

I didn't implement nosniff for CSS because I thought we were strictly checking text/css types. It looks like we're not doing that in quirks mode, which is surprising. I filed https://bugs.chromium.org/p/chromium/issues/detail?id=788096 to look into it.

mikewest avatar Nov 23 '17 08:11 mikewest

Filed https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/14802116/ against Edge. Adding an example seems like a good idea. Let me know if you want to take that up.

annevk avatar Nov 23 '17 11:11 annevk

Hi! I'd like to work on this issue as my first contribution. Can I go ahead with it?

AdapaRohith avatar Jul 29 '25 13:07 AdapaRohith