Fix typical IIS 10 vulnerabilities and ace your security audit

If you’re using IIS 10, you’ll need to pass those security audits. Here are some typical things that aren’t configured right out of the box, and how to fix them.

David Mold
7 min readFeb 29, 2020
Don’t wait for the horse to bolt

You will generally be in good shape using IIS 10 to securely host websites, but there are some changes you must make to pass a security audit.

Although many potential security flaws may lurk in the applications you host (and you’ll need to attend to those for sure), the more predictable ones can be dealt with at the server level. You’ll want to be certain your web sites can survive a security audit before your client asks for one, so here are the typical extra configurations you’ll need to add so it passes with flying colors.

This isn’t an exhaustive list, but includes the main issues I have repeatedly encountered over the last several years in my work maintaining professional web sites for top-tier corporations.

Keep your cookies safe

A lot of sites use cookies, especially for authentication. In many cases, the application running on the site doesn’t need to access these cookies with client-side JavaScript. In this situation, you should always secure your cookies by setting them to be httpOnly.

Even if your application does access cookies through client-side JavaScript, you should set the secure flag. This ensures that the cookies can only be accessed using SSL, adding another layer of security to your cookie use. You can do this very simply by editing the web.config file for your site or application.

Just add the following to the system.web element of each site’s web.config file:

<httpCookies domain="String" 
httpOnlyCookies="true"
requireSSL="true" />

The requireSSL value sets the secure flag, and the httpOnlyCookies value does just what you would expect. If you really can’t have httpOnly cookies, just set that value to “false” instead.

Don’t allow non-HTTPS connections

These days every site should be using SSL, of course. But you probably also have your websites mapped to port 80, just in case people type in the URL without using https. You need to redirect those users to the SSL version and you need to make sure they can’t access any non-SSL resources on the website. You can handle all this easily at the website level using IIS’s URL Rewrite module.

If you don’t see it in IIS manager, you may need to install this indispensable module. That’s easily done by following the instructions here. Once that’s done, open URL Rewrite at the level of each website you want to protect, add a new blank rule and enter the settings shown below:

In the rewrite section of your web.config file, the rule will look like this:

<rule name="ssl-redir" stopProcessing="true">
<match url="(.*)" />
<conditions logicalGrouping="MatchAll" trackAllCaptures="false">
<add input="{HTTPS}" pattern="off" />
</conditions>
<action type="Redirect" url="https://{HTTP_HOST}/{R:1}"
redirectType="Permanent" />
</rule>

You can see in the Match URL section we are just matching all patterns. In the Conditions section, we look for HTTPS being “off”. Then in the Action section, the redirect is set to the same website but using the https protocol. This guarantees that visitors can only access all resources via SSL, whether it’s web pages, images, scripts, json, PDFs or any other kind of content. Simple.

Remove all of IIS’s branded response headers

This next one is more complex and involves several different configurations. If you open the web page of one of your sites in Firefox or Google, and use the developer tools to look at the response headers for a web page, you will be likely to see something like this:

Ooh, what a giveaway!

I’ve highlighted the two problem headers: server and x-powered-by. They tell hackers which software and version you are using, to make it super-easy for them to attack your site. So they have to go. To get rid of the X-powered-by header, add the highlighted lines in each web site’s web.config file.

In order to remove the server response header, you will need to crack open Powershell. Find it by typing Powershell in the search bar, and then type the following (just one line):

Set-WebConfigurationProperty -pspath 'MACHINE/WEBROOT/APPHOST'  -filter "system.webServer/security/requestFiltering" -name "removeServerHeader" -value "True"

No need to reboot after that one.

You gotta have a policy

In order to stop those crafty potential intruders from finding ways to hijack your site, it’s a good idea to set up a referrer policy. Depending on how your applications work, it’s sometimes possible to leak information to external websites because when a web browser follows a link from one site to another, it sends a “referer” (yes, that misspelling is correct) header, which the next website can read. If the URL of one of your pages contains sensitive information (perhaps a user logs in and the URL path includes their name or ID number), we don’t want to send it in the request to an external site. And you can use a referrer policy header to prevent it.

I suggest using the confusingly named origin-when-cross-origin value, because that ensures that whenever referrer information is sent outside the bounds of your site, it only contains the domain name and not the specific page URL in the referer header. In the same place that you removed the X-Powered-By header above (the system.webServer section of web.config), you can use the custom headers settings to add a Referrer-Policy header as follows:

<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Referrer-Policy" value="origin-when-cross-origin" />
</customHeaders>
</httpProtocol>

And yes, in this case referrer needs to be spelled correctly.

What the HSTS?

HSTS stands for Http Strict Transport Security. At the server end, it is nothing more than a header that your web server can set to insist that web browsers connect via SSL. Why do you need to do this when you have just enforced SSL using the rewrite rules above? Well, hackers can use packet sniffers to redirect traffic that relies on 301 redirects alone to enforce SSL. Because your users’ web browsers will insist on using SSL to connect to your site, it means attempts to intercept traffic between users and your site should fail.

So we just need to add another header as we did with the referrer policy above, so that section in web.config under system.webServer will now look like this:

<httpProtocol>
<customHeaders>
<remove name="X-Powered-By" />
<add name="Referrer-Policy" value="origin-when-cross-origin" />
<add name="Strict-Transport-Security" value="max-age=31536000" />
</customHeaders>
</httpProtocol>

Now, when you load a page in your browser and inspect the headers, you should see the new header:

HSTS header added, viewd in Firefox

Changing the Cryptography Settings

Fixing IIS cryptography settings would be the hardest of all, if it weren’t for a very useful and free piece of software called IISCrypto. Get the latest version and install that, it works on all versions of Windows Server from 2008 onwards. When you run it, you’ll see its Best Practices button in the bottom right hand corner, so just click that, and once you click Apply, it’s all done except for the reboot. However, some clients will have stricter requirements for which protocols to support, so you may have some additional items to disable. I have found myself needing to disable all versions of TLS below 1.2 (although be aware this will prevent a few older browsers from accessing the site).

You may also need to disable some cipher suites, so if you need to, click on that button in the left navigation:

At this time, these are the only cipher suites that are recommended, but of course that will change over time.

Now reboot your server. Check your website’s SSL setup by visiting SSLLabs’ SSL Server Test page, and entering your domain name. They will give you a security rating based on the changes you’ve made. If you’ve done everything above, you should be looking at an A+ rating.

--

--