To make sure that only the correct file types are served by your IIS, you should review the file extensions.
Even if you are using MVC rather than WebForms, you still may have certain static files served by IIS, to start lets find out which file types you are using, navigate into your web documents directory in PowerShell and run:
get-childitem . -recurse | where-object {$_.psiscontainer -eq $false} | Group-Object -property Extension -noelement | sort-object -property Count -descending
For twee.net this returned:
Count Name
----- ----
2449 .html
408 .jpg
289 .gif
61 .aspx
32 .png
24 .xml
23 .css
16 .js
13 .xsl
12 .db
11 .dll
10 .ascx
6 .config
4 .txt
4 .cshtml
3 .htm
2 .pda
1 .asmx
1 .ico
1 .asax
1 .mpg
First of all, you should review these extension, are there any you don't recognise? In my case what are the .db, .xsl, .htm and .pda
files?
Review them with:
get-childitem . -recurse | ? {$_.Extension -imatch "(htm|db|xsl|pda)$"}
You may want to remove them completely, like:
get-childitem . -recurse -Include thumbs.db | Remove-Item
Next put the extensions into categories:
Category 1 - static files to be served directly:
.css
.gif
.htm
.html
.ico
.jpg
.js
.mpg
.png
.txt
.xml
You want to make sure that these exentions are present in the MIME Types of your site, but not only should they be present, they should be the only types there. The easiest way to do this is editing the web.config files in the root of your site, inside the system.webServer
node add:
<staticContent>
<clear/>
<mimeMap fileExtension=".css" mimeType="text/css" />
<mimeMap fileExtension=".gif" mimeType="image/gif" />
<mimeMap fileExtension=".htm" mimeType="text/html" />
<mimeMap fileExtension=".html" mimeType="text/html" />
<mimeMap fileExtension=".ico" mimeType="image/x-icon" />
<mimeMap fileExtension=".jpg" mimeType="image/jpeg" />
<mimeMap fileExtension=".js" mimeType="application/javascript" />
<mimeMap fileExtension=".mpg" mimeType="video/mpeg" />
<mimeMap fileExtension=".png" mimeType="image/png" />
<mimeMap fileExtension=".txt" mimeType="text/plain" />
<mimeMap fileExtension=".xml" mimeType="text/xml" />
</staticContent>
Category 2 - Files that should be processed by an Application framework:
.asmx
.aspx
You want to make sure these extensions are present in the Handler Mappings
Category 3 - files never to be served:
.asax
.ascx
.config
.cshtml
.dll
.xsl
Make sure they are present in File Name Extensions
under Request Filtering
, in my case some were missing, to add them use:
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/siteName' -filter "system.webServer/security/requestFiltering/fileExtensions" -name "." -value @{fileExtension='.dll';allowed='False'}
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/siteName' -filter "system.webServer/security/requestFiltering/fileExtensions" -name "." -value @{fileExtension='.xsl';allowed='False'}
Add-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST/siteName' -filter "system.webServer/security/requestFiltering/fileExtensions" -name "." -value @{fileExtension='.cshtml';allowed='False'}
This results into something like:
<security>
<requestFiltering>
<fileExtensions>
<add fileExtension=".dll" allowed="false" />
<add fileExtension=".xsl" allowed="false" />
<add fileExtension=".cshtml" allowed="false" />
</fileExtensions>
</requestFiltering>
</security>
inside the system.webServer
node in your web.config
Note that .dll is not there by default because bin
is a protected location already, but it can't hurt to deny access twice.
On twee.net you can also download PDF and ZIP files, they don't show up in the file extension listing and also not in the list of allowed extentions. How do they work?
It is good practice to store certain files outside of your webRoot, in the old days there were no Hidden Segments
or Mime Type Restrictions
. So rather than linking directly to the file to be downloaded, all links are to a helper-URL which verifies a requested download and then pushes the file down to the client.
This helper sets the MIME-Type and file extension dynamically, the IIS restriction above only apply to static files.
If you own all sites on your server, you can apply these hardening messures to the machine level rather than the site level. If you then need special extensions for a particular site, just allow that one in your web.config