Why does Content-Type and Extension matter?
Applications come in many different shapes and sizes and XSS can occur all over the place. It's easy to assume that just because an application returns you a response with unfiltered/unencoded output you've found an exploitable XSS issue but this is often not the case. Browsers render content based on a number of factors including content-type returned by the server, page content and page extension, without the correct combination XSS won't be possible.
In the first test I forced the server to return the correct extension and content-type for each test page.
Test #2 - Modifying Extension
In the second test I made the server return the correct content-type but forced a .html extension.
This test seemed to show that browsers will prioritize the use of the content-type over the extension.
Test #3 - Using a text/html Content-Type
In the third test I used the correct extension for each file but made the server return a text/html content-type.
It looks like browsers rely heavily on the content-type returned by the server. It doesn't matter about the extension or contents of the file, the browser will blindly follow the content-type returned.
Test #4 - Using a text/plain Content-Type
Next I used the correct extension for each file but made the server return a text/plain content-type.
When using a content-type of text/plain none of the payloads executed. I can't remember for sure, but I believe in the past text/plain used to allow XSS? Looks like this is no longer possible.
Test #5 - MIME sniffing
In this last test case I accessed a page that had no extension and received no content-type header from the server. This should have caused the browser to fall back on mime sniffing to render the page.
Both Chrome and Firefox refused to render pages that contained additional non-html content. IE however didn't seem to care what the page content was, if it contained HTML it rendered!
Performing application testing on a regular basis I find content-type and extension XSS issues arise quite a lot. This test showed that modern browsers are relatively secure as long as the correct content-type is returned. All browsers also seemed to implement the same analysis techniques aside from IE which seemed slightly more permissive.
Hopefully you guys have found this post useful, if anyone has any suggestions for bypasses to achieve XSS in any of the above, or if I've listed any findings incorrectly (quite possible) drop me a message below :)