MIME-Handling Changes in Internet Explorer
Each type of file delivered from a web server has an associated MIME type (also called a “content-type”) that describes the nature of the content (e.g. image, text, application, etc). Back in Internet Explorer 8, we made a few changes to IE’s MIME-sniffing feature that attempts to determine the actual content-type for each downloaded resource. In this post, I discuss how recent changes to IE further improve MIME-handling and make browsing more secure.
Certain HTML elements (LINK and SCRIPT in particular) historically have not attempted to validate the MIME-type supplied by the server. For instance, all browsers will run script even if the SCRIPT’s SRC attribute points at a file declaring that it is text/plain. This can lead to a variety of security vulnerabilities, particularly for LINK elements. There is a rich object model for interacting with stylesheets, and this object model can be abused if the “stylesheet” contains other content.
In an attack scenario, a malicious site could include a LINK reference pointing at another site’s HTML content. If that HTML content contained certain common characters, its content could be read by script in the attacker’s page. This information disclosure could lead to cross-site request forgery and other attacks against web applications. You can learn more about this threat in a paper from Carnegie-Mellon University.
In the October Cumulative update, a change was made to CSS handling in IE6, IE7, and IE8 to block all cross-origin stylesheets unless they have been delivered with the proper HTTP response header:
Content-Type: text/css
This protection helps ensure that LINK and @IMPORT cannot be used as a vector to steal content from another site.
Internet Explorer 9 Beta already included this protection. Additionally, the F12 Developer Tools’ Console included in IE9 shows the following warning message when a cross-origin stylesheet with an incorrect MIME-type is encountered:
Further IE9 Improvements
Beyond the cross-origin stylesheet validation introduced for all versions, Internet Explorer 9 Beta includes some other important changes to MIME-handling behavior to improve security and standards-compliance. These changes could cause problems when displaying content if the Content-Type information is missing or incorrect. The three MIME-handling changes introduced by IE9 are:
- In IE9 Standards Mode, even same-origin stylesheets will be ignored unless they are delivered with a text/css MIME type.
- SCRIPT elements will reject responses with incorrect MIME types if the server specifies X-Content-Type-Options: nosniff.
- Documents delivered with a text/plain MIME type will not be MIME-sniffed to another type.
Change #1 is a requirement of the CSS specification and applies MIME-type validation to same-origin stylesheets when if document is running in IE9 Standards Mode. A concise test case displays red text if a browser applies styles from a stylesheet with an incorrect MIME-type; it renders the text in green if the invalid stylesheet is correctly ignored.
Change #2 impacts the browser’s behavior when the server sends the X-Content-Type-Options: nosniffheader on its responses. If the nosniff directive is received on a response retrieved by a SCRIPT reference, IE will not load the “script” file if the MIME type does not match one of the following values ["text/javascript", "application/javascript", "text/ecmascript", "application/ecmascript", "text/x-javascript", "application/x-javascript", "text/jscript", "text/vbscript", "text/vbs"]. When such content is blocked, the F12 developer tools show the following message:
This new protection recently impacted a major site which was delivering JSONP responses with a nosniff header but without a proper JavaScript MIME-type. The site owners have since corrected the misconfiguration.
Change #3 is perhaps the most welcome for many web developers. If IE9 encounters a HTML document delivered with a text/plain content-type, the document will be rendered as plain text unless the site is rendering in Compatibility View. This is useful for web developer scenarios because it allows easier sharing of HTML source code snippets. It’s also a welcome change from a security point-of-view, because IE9 will be less susceptible to script injection attacks in files delivered with a text/plain Content Type.
If you find any sites which are sending improper MIME types and behave incorrectly in Internet Explorer, please file a bug on Connect!
Thanks,
Eric Lawrence
Program Manager
Comments
Anonymous
October 26, 2010
This is great to hear. What are the IE team's plans regarding UTF-7? As you may know, HTML5 requires browsers not to support it, and all available evidence is that on the public web it's only used for exploits (specifically, for "universal XSS" bypass of server-side filters).Anonymous
October 26, 2010
Nice to see the PLAIN/TEXT changes.Anonymous
October 26, 2010
The comment has been removedAnonymous
October 26, 2010
Eric - Thanks for the update (and for your willingness to be on these forums as much as you are ;-) ). On a related note to this discussion, are there any plans to support the"overrideMimeType" method for XMLHttpRequest for IE9, as it is supported in other browsers? Cheers,
- Bill
Anonymous
October 26, 2010
I welcome the stricter checking of MIME-type, but I don't see that #1 really enhances security.Anonymous
October 26, 2010
Nice changes. #3 has been requested forever. IIRC, Mozilla changed their behavior to match the broken IE behavior awhile back. I wonder what they're going to do now. It's also nice to see support for application/javascript and application/ecmascript. Is this also supported on the |script| element's |type| attribute? How about the |version| parameter for those MIME types (specified by the same document that specifies those MIME types)? Now if only ya'll would support the correct MIME types for XSLT (application/xml and application/xslt+xml). (The XSLT 2.0 spec still claims that the latter is still undergoing IANA review, but it appears to have been approved.) As far as I can tell, there's no way to get an XSLT-styled document to work in both WIE and non-WIE browsers while following a standard and the touted "same markup" principle. You have to use an |xsl-stylesheet| PI with |type="text/xsl"| instead. @jabcreations: Given that your first paragraph doesn't make sense (due to grammatical errors), I'm not sure what you're trying to say. If you're saying that WIE is emulating Safari by parsing the document up to the error and rendering the part of the document processed up to that error, that would seem to be permitted by the XML 1.0 spec. From a user perspective, that makes a lot more sense too; I'd presume that most users would rather see /some/ content instead of an error message. (It still needs to be obvious that an error occurred though.)Anonymous
October 26, 2010
Nice changes. #3 has been requested forever. IIRC, Mozilla changed their behavior to match the broken IE behavior awhile back. I wonder what they're going to do now. It's also nice to see support for application/javascript and application/ecmascript. Is this also supported on the |script| element's |type| attribute? How about the |version| parameter for those MIME types (specified by the same document that specifies those MIME types)? Now if only ya'll would support the correct MIME types for XSLT (application/xml and application/xslt+xml). (The XSLT 2.0 spec still claims that the latter is still undergoing IANA review, but it appears to have been approved.) As far as I can tell, there's no way to get an XSLT-styled document to work in both WIE and non-WIE browsers while following a standard and the touted "same markup" principle. You have to use an |xsl-stylesheet| PI with |type="text/xsl"| instead. @jabcreations: Given that your first paragraph doesn't make sense (due to grammatical errors), I'm not sure what you're trying to say. If you're saying that WIE is emulating Safari by parsing the document up to the error and rendering the part of the document processed up to that error, that would seem to be permitted by the XML 1.0 spec. From a user perspective, that makes a lot more sense too; I'd presume that most users would rather see /some/ content instead of an error message. (It still needs to be obvious that an error occurred though.)Anonymous
October 27, 2010
I wish you'd stop involving MIME into this, and start calling them by their real designation — media types. tools.ietf.org/.../rfc2616Anonymous
October 27, 2010
The comment has been removedAnonymous
October 27, 2010
@Patrick Garies XHTML when correctly served as application/xhtml+xml is supposed to be well formed meaning lacking malformed XML. If an error occurs the page is supposed to break and display an error message. The point of this is to encourage better written code. Browsers should only support this mode ANY WAY, so much time is wasted in browser development to determine how to interpret how to handle non-code that looks like code.Anonymous
October 27, 2010
The comment has been removedAnonymous
October 28, 2010
@anon It works for users to tell them the site they are visiting isn't correctly coded whereas if they don't see the error message then they will expect that same broken code to work. I'd rather know a site has an error and come back later...if at all. What you're saying makes no sense because if designers (and developers outsourced to do design) aren't aware of errors then they aren't going to know to fix them. Actually the best way to handle the issue is how Opera handles it, offer to render the page as regular HTML when displaying the malformed XHTML error message.Anonymous
October 28, 2010
@jabcreations: I know the difference between XML and HTML MIME types. What I was saying is that the XML spec does not mandate that you replace everything processed with an error message (i.e., the "yellow screen of death") when an error is encountered. It requires that processing stop, but doesn't otherwise say what should be rendered. Some implementors have chosen to render the code that was already processed before the parser hit the XML error.Anonymous
October 29, 2010
text/plain and others are still sniffed for CSS content when the document is loaded locally, see issue 618125@Connect.Anonymous
October 30, 2010
@the_dees: By default, documents loaded "locally" aren't in IE9 browser mode. Hence, by-design.Anonymous
November 01, 2010
@jabcreations IE9's handling of XML errors complies with what is defined by the XML specification (see www.w3.org/.../REC-xml). How those errors are displayed is aimed at balancing end-user and developer requirements. Most end-users have no idea what an XML error is, nor can they do anything about it, so we chose to avoid confusing them with the error details. We also chose to present them with the content occuring before the point of failure so they would have some hope of getting at the information they were looking for. To continue to support developers, we moved the notification and details for XML parsing errors into the developer toolbar, which is more consistent with the notification model for other types of developer-oriented errors, such as those generated from script.Anonymous
November 01, 2010
Tony posted a longer blog about the XHTML MIME type here: blogs.msdn.com/.../xhtml-in-ie9.aspx