When you run an online security vulnerability assessment tool, such as the one available at Pentest-Tools.com, one of the recommendations you’ll often run into is to set a few security-related response headers, including X-Frame-Options, X-Xss-Protection, and X-Content-Type-Options.
X-Frame-Options allows you to control whether your site can be loaded within an IFrame; possible values include DENY, SAMEORIGIN, and ALLOW-FROM. DENY means that a browser should not display the site in an IFrame, whereas SAMEORIGIN will allow a site to be loaded in an IFrame as long as it’s on the same domain (depending on the browser implementation, subdomains may or may not work). The ALLOW-FROM option allows an administrator to provide a list of domains that are allowed to display the site in an IFrame. The DENY option is generally recommended.
X-Xss-Protection provides options to determine how a browser should act when they detect a cross-site scripting attack. Setting this header to 0 turns off the filtering, a value of 1 means that the part of the page containing the attack is sanitized (removed), and a value of 1; mode=block will stop the entire page from rendering. This last value is recommended.
X-Content-Type-Options has a single option: nosniff. This means that the browser does not attempt to determine the type of a file based on its contents; it will only use the Content-Type header.
We were able to add these headers to our responses by adding the following section to our web.config file:
<system.webServer> <httpProtocol> <customHeaders> <add name="X-Frame-Options" value="SAMEORIGIN" /> <add name="X-Xss-Protection" value="1; mode=block" /> <add name="X-Content-Type-Options" value="nosniff" /> </customHeaders> <httpProtocol> </system.webServer>
It was this last header, X-Content-Type-Options, that caused our issues.
The file that caused us grief is the Resource Manager, which can be found at (depending on your language):
Thankfully, because we have the full source code with the xRM Portals Community Edition, we are able to see what’s going on. The files of interest are:
If you look in the ResourceController.cs file, you’ll see that the Content-Type header is being set:
However, that line of code does not do anything. It seems to be an MVC issue; whatever you set as the ContentType in the controller is not respected if you return a View.
The recommended solution I found with the help of Google was to include the following line on the view itself:
However, this still didn’t do the trick. For some reason, this didn’t work if the view being returned was a user control (.ascx). So, I renamed the file from ResourceManager.ascx to ResourceManager.aspx, and replaced the first two lines in the file with the following:
While the Microsoft-hosted Dynamics 365 Portals do exhibit this same issue, it doesn’t cause any errors because we aren’t able to add the X-Content-Type-Options: nosniff header to our responses since we don’t have access to the code. That being said, hopefully this is something that Microsoft will resolve in a future release, as it was clearly their intention to set the proper content type header.