Difference between revisions of "Hardening IIS"

From OWASP
Jump to: navigation, search
m (Formatted the layout of the headers.)
(Configure maxAllowedContentLength)
 
(9 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
= Draft - Work In Progress =
 
= Draft - Work In Progress =
  
=== Basic configuration ===
+
== Basic configuration ==
  
==== Disable directoryBrowsing ====
+
Common changes that should be part of all IIS installations.
  
==== Avoid wildcard host headers ====
+
=== Disable directoryBrowsing ===
  
==== Ensure applicationPoolIdentity is configured for all application pools ====
+
Directory browsing gives the user the ability to just navigate to http://server/directory/ and get a list of all files in the directory.  This was useful when web servers were primarily file servers, but is clearly a security problem now.
  
==== Use an unique applicationPool per site ====
+
To disable directory browsing in IIS 10.0 (and several earlier versions, either:
  
==== Disable IIS detailed error page from displaying remotely ====
+
1) Alter the web.config to set the directoryBrowse feature to false
  
=== Request filtering ===
+
  <configuration>
 +
      <system.webServer>
 +
        <directoryBrowse enabled="false" />
 +
      </system.webServer>
 +
  </configuration>
  
==== Configure maxAllowedContentLength ====
+
2) or Navigate to IIS in the Server Manager, and uncheck Directory Browsing under Common HTTP Features.
  
==== Configure maxURL request filter ====
+
=== Avoid wildcard host headers ===
  
==== Configure MaxQueryString request filter ====
+
IIS 10.0 has added wildcard host headers.  This means that if there is a website hosted for a domain, the server will handle requests for any subdomain, allowing the developer to make decisions based on the request as how to respond.
  
==== Reject non-ASCII characters in URLs ====
+
In general, this is a bad idea and shouldn't be used.  There are very specific reasons to use them, but it is almost guaranteed that your situation isn't one of them.
  
==== Reject double-encoded requests ====
+
Certainly, do not use wildcard domains, like http://* for example.  But in general avoid using them at all.  Instead use site bindings to solve the same problem.
  
==== Disable HTTP trace requests ====
+
=== Ensure applicationPoolIdentity is configured for all application pools ===
 +
applicationPoolIdentity configured the Active Directory user that the applications in the pool impersonate. 
  
==== Disallow unlisted file extensions ====
+
To assure that this value is set, navigate to an Application Pool in IIS Manager, right click and select Application Pool defaults.  Then select the appropriate user.
  
==== Enable Dynamic IP Address Restrictions ====
+
=== Use an unique applicationPool per site ===
  
=== Transport Encryption ===
+
Application bools are designed to create a collection of sites that can be restarted together, and have a common max memory limit, and some other features.  With today's applications, it is best if there is a unique application pool for each site.  Perhaps if there is a separate project for services and the front end of an application, then they could go together in one pool but for the majority of applications, one pool per app.=
  
==== SSL/TLS settings are controlled at the SChannel level. They are set machine wide and IIS respects these values. ====
+
There are two ways to configure application pools for IIS.  
  
==== A list of recommendations for IIS ====
+
1)In IIS Manager, expand Sites in the Connections pane.  Then click Advanced Settings, then the ellipsis button next to Application Pool. Select a unique pool there.
  
===== Disable SSL v2/v3 =====
+
2) Using the command prompt, run appcmd to set up new command pools.
  
===== Disable TLS 1.0 =====
+
  appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='NewCommandPool',autoStart='True',managedPipelineMode='Integrated']" /commit:apphost
  
===== Disable TLS 1.1 =====
+
=== Disable IIS detailed error page from displaying remotely ===
  
===== Ensure TLS 1.2 is enabled =====
+
When debugging a production application that is misbehaving, we would like to see detailed errors when using the server at the console, but show remote users custom pages.
  
===== Disable weak cipher suites (NULL cipher suites, DES cipher suites, RC4 cipher suites, Triple DES, etc) =====
+
To handle this, use the IIS Console and select Exceptions.  In the Actions column, select Edit Feature Settings and then select Detailed Errors For Local Requests and Custom Errors For Remote Requests.
  
===== Ensure TLS cipher suites are correctly ordered =====
+
== Request filtering ==
 +
 
 +
=== Configure maxAllowedContentLength ===
 +
The maxAllowedContentLength is a part of the requestLimits collection, and it is too long by default for most requests (around 26 MB).  On an application bases it can be altered using the requestFiltering node in the Security collection.  Here is an example in the web.config:
 +
 
 +
  <configuration>
 +
      <system.webServer>
 +
        <security>
 +
            <requestFiltering>
 +
              <requestLimits>
 +
                  <headerLimits>
 +
                    <add header="Content-type" sizeLimit="100" />
 +
                  </headerLimits>
 +
              </requestLimits>
 +
            </requestFiltering>
 +
        </security>
 +
      </system.webServer>
 +
  </configuration>
 +
 
 +
In C#, it is possible to change the content length for a particular request with the ServerManager:
 +
 
 +
      using (ServerManager serverManager = new ServerManager())
 +
      {
 +
        Configuration config = serverManager.GetWebConfiguration("Default Web Site");
 +
        ConfigurationSection requestFilteringSection = config.GetSection("system.webServer/security/requestFiltering");
 +
        ConfigurationElement requestLimitsElement = requestFilteringSection.GetChildElement("requestLimits");
 +
        ConfigurationElementCollection headerLimitsCollection = requestLimitsElement.GetCollection("headerLimits");
 +
   
 +
        ConfigurationElement addElement = headerLimitsCollection.CreateElement("add");
 +
        addElement["header"] = @"Content-type";
 +
        addElement["sizeLimit"] = 100;
 +
        headerLimitsCollection.Add(addElement);
 +
   
 +
        serverManager.CommitChanges();
 +
      }
 +
 
 +
=== Configure maxURL request filter ===
 +
 
 +
=== Configure maxQueryString request filter ===
 +
 
 +
=== Reject non-ASCII characters in URLs ===
 +
 
 +
=== Reject double-encoded requests ===
 +
 
 +
=== Disable HTTP trace requests ===
 +
 
 +
=== Disallow unlisted file extensions ===
 +
 
 +
=== Enable Dynamic IP Address Restrictions ===
 +
 
 +
== Transport Encryption ==
 +
 
 +
=== SSL/TLS settings are controlled at the SChannel level. They are set machine wide and IIS respects these values. ===
 +
 
 +
=== A list of recommendations for IIS ===
 +
 
 +
==== Disable SSL v2/v3 ====
 +
 
 +
==== Disable TLS 1.0 ====
 +
 
 +
==== Disable TLS 1.1 ====
 +
 
 +
==== Ensure TLS 1.2 is enabled ====
 +
 
 +
==== Disable weak cipher suites (NULL cipher suites, DES cipher suites, RC4 cipher suites, Triple DES, etc) ====
 +
 
 +
==== Ensure TLS cipher suites are correctly ordered ====
 
https://cloudblogs.microsoft.com/microsoftsecure/2017/09/07/new-iis-functionality-to-help-identify-weak-tls-usage/
 
https://cloudblogs.microsoft.com/microsoftsecure/2017/09/07/new-iis-functionality-to-help-identify-weak-tls-usage/
  
=== HSTS support ===
+
== HSTS support ==
  
==== IIS recently (Windows Server 1709) added turnkey support for HSTS ====
+
=== IIS recently (Windows Server 1709) added turnkey support for HSTS ===
 
https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10-version-1709/iis-10-version-1709-hsts
 
https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10-version-1709/iis-10-version-1709-hsts
  
=== CORS support ===
+
== CORS support ==
  
==== If you choose not to handle CORS in your application, we ship an IIS an IIS module to help configure CORS ====
+
=== If you choose not to handle CORS in your application, we ship an IIS an IIS module to help configure CORS ===
 
https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
 
https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module
  

Latest revision as of 20:29, 28 August 2018

Draft - Work In Progress

Basic configuration

Common changes that should be part of all IIS installations.

Disable directoryBrowsing

Directory browsing gives the user the ability to just navigate to http://server/directory/ and get a list of all files in the directory. This was useful when web servers were primarily file servers, but is clearly a security problem now.

To disable directory browsing in IIS 10.0 (and several earlier versions, either:

1) Alter the web.config to set the directoryBrowse feature to false

  <configuration>
     <system.webServer>
        <directoryBrowse enabled="false" />
     </system.webServer>
  </configuration>

2) or Navigate to IIS in the Server Manager, and uncheck Directory Browsing under Common HTTP Features.

Avoid wildcard host headers

IIS 10.0 has added wildcard host headers. This means that if there is a website hosted for a domain, the server will handle requests for any subdomain, allowing the developer to make decisions based on the request as how to respond.

In general, this is a bad idea and shouldn't be used. There are very specific reasons to use them, but it is almost guaranteed that your situation isn't one of them.

Certainly, do not use wildcard domains, like http://* for example. But in general avoid using them at all. Instead use site bindings to solve the same problem.

Ensure applicationPoolIdentity is configured for all application pools

applicationPoolIdentity configured the Active Directory user that the applications in the pool impersonate.

To assure that this value is set, navigate to an Application Pool in IIS Manager, right click and select Application Pool defaults. Then select the appropriate user.

Use an unique applicationPool per site

Application bools are designed to create a collection of sites that can be restarted together, and have a common max memory limit, and some other features. With today's applications, it is best if there is a unique application pool for each site. Perhaps if there is a separate project for services and the front end of an application, then they could go together in one pool but for the majority of applications, one pool per app.=

There are two ways to configure application pools for IIS.

1)In IIS Manager, expand Sites in the Connections pane. Then click Advanced Settings, then the ellipsis button next to Application Pool. Select a unique pool there.

2) Using the command prompt, run appcmd to set up new command pools.

 appcmd.exe set config -section:system.applicationHost/applicationPools /+"[name='NewCommandPool',autoStart='True',managedPipelineMode='Integrated']" /commit:apphost

Disable IIS detailed error page from displaying remotely

When debugging a production application that is misbehaving, we would like to see detailed errors when using the server at the console, but show remote users custom pages.

To handle this, use the IIS Console and select Exceptions. In the Actions column, select Edit Feature Settings and then select Detailed Errors For Local Requests and Custom Errors For Remote Requests.

Request filtering

Configure maxAllowedContentLength

The maxAllowedContentLength is a part of the requestLimits collection, and it is too long by default for most requests (around 26 MB). On an application bases it can be altered using the requestFiltering node in the Security collection. Here is an example in the web.config:

  <configuration>
     <system.webServer>
        <security>
           <requestFiltering>
              <requestLimits>
                 <headerLimits>
                    <add header="Content-type" sizeLimit="100" />
                 </headerLimits>
              </requestLimits>
           </requestFiltering>
        </security>
     </system.webServer>
  </configuration>

In C#, it is possible to change the content length for a particular request with the ServerManager:

     using (ServerManager serverManager = new ServerManager())
     {
        Configuration config = serverManager.GetWebConfiguration("Default Web Site");
        ConfigurationSection requestFilteringSection = config.GetSection("system.webServer/security/requestFiltering");
        ConfigurationElement requestLimitsElement = requestFilteringSection.GetChildElement("requestLimits");
        ConfigurationElementCollection headerLimitsCollection = requestLimitsElement.GetCollection("headerLimits");
   
        ConfigurationElement addElement = headerLimitsCollection.CreateElement("add");
        addElement["header"] = @"Content-type";
        addElement["sizeLimit"] = 100;
        headerLimitsCollection.Add(addElement);
   
        serverManager.CommitChanges();
     }

Configure maxURL request filter

Configure maxQueryString request filter

Reject non-ASCII characters in URLs

Reject double-encoded requests

Disable HTTP trace requests

Disallow unlisted file extensions

Enable Dynamic IP Address Restrictions

Transport Encryption

SSL/TLS settings are controlled at the SChannel level. They are set machine wide and IIS respects these values.

A list of recommendations for IIS

Disable SSL v2/v3

Disable TLS 1.0

Disable TLS 1.1

Ensure TLS 1.2 is enabled

Disable weak cipher suites (NULL cipher suites, DES cipher suites, RC4 cipher suites, Triple DES, etc)

Ensure TLS cipher suites are correctly ordered

https://cloudblogs.microsoft.com/microsoftsecure/2017/09/07/new-iis-functionality-to-help-identify-weak-tls-usage/

HSTS support

IIS recently (Windows Server 1709) added turnkey support for HSTS

https://docs.microsoft.com/en-us/iis/get-started/whats-new-in-iis-10-version-1709/iis-10-version-1709-hsts

CORS support

If you choose not to handle CORS in your application, we ship an IIS an IIS module to help configure CORS

https://blogs.iis.net/iisteam/getting-started-with-the-iis-cors-module

Authors

Sourabh Shirhatti (Microsoft)

Bill Sempf (bill.sempf@owasp.org)