The IIS 7.5 Application Warm-Up Module

IIS is a demand-driven web server, i.e. IIS does things only when asked for. For example: an IIS worker process spawns up only when requests arrive for the sites that are hosted in this worker process. Without requests there isn’t a worker process. This is great from a resource consumption point of view. Worker processes which don’t run do not consume resources, memory in particular.

There is a drawback to this architecture however. The first requests that get handled by a newly spawned worker process might have to wait longer due to the initialization costs of the web application(s) living within the worker process. Typical example of initialization activities are:

  • Initialization of data structures
  • Loading data from a datastore into memory  (caching)
  • Compilation of code, e.g. .NET applications
  • Establishing database connections

To resolve this issue, install Application Initialization for IIS 7.5

Application Initialization for IIS 7.5

  • Improved customer experience while the Application is warming up

  • Decrease the response time for first requests by pre-loading worker processes

  • Increase reliability by pre-loading worker processes when Overlapped Recycling occurs

Security configurations for MVC application & IIS 7

After Sony had been hacked earlier this year, they start taking security really serious now.

And recently I have been involved in a few Sony promotion projects that makes me learn a lot about how to make a website more securer from both web server configurations and application itself.

Go through a 50 pages configuration benchmark book is a pain, but there are some really simple steps people easily forget. Here are some highlights:

  1. Make sure web content is on non-system partition.
  2. Remove or rename well-known urls.
    %systemdrive%\inetpub\AdminScripts
    %systemdrive%\inetpub\scripts\IISSamples
    http://localhost/iissamples
    http://localhost/iishelp
    http://localhost/printers
    http://localhost/iisadmpwd
  3. Require a host headers on all sites. Don’t bind http:/*:80 to any site.
  4. Disable directory browsing
  5. Set default application pool identity to least privilege principal.
  6. Ensure application pools run under unique identities, and unique application pools for different sites.
  7. Config anonymous user identity to use application pool identity, this will greatly reduce the number of accounts needed for websites.
    open applicationHost.config and make sure you set the userName attribute of the anonymousAuthentication tag is set to a blank string.

    <system.webServer><security><authentication><anonymousAuthentication userName = ""/></authentication></security></system.webServer>
  8. Configure authentications,

    a. Ensure sensitive site features is restricted to authenticated principals only.

    <system.webServer><security><authorization><remove users="*" roles="" verbs="" /><add accessType="Allow" roles="administrators" />
    
    </authorization></security></system.webServer></configuration>

    b. Require SSL in forms authentications and configure forms authentication to use cookies.

    <pre><system.web><authentication><forms cookieless="UseCookies" requireSSL="true" /></authentication></system.web></pre>

    c. Configure cookie protection mode for forms authentication.

    <pre><system.web><authentication><forms cookieless="UseCookies" protection="All" /></authentication></system.web></pre>

    d. Never save password in clear format!!

  9. Asp.net configurations.

    a. Set deployment method to retail, modify machine.config

    <system.web>  <deployment retail="true" /></system.web>

    b. Turn debug off.

    <system.web><compilation debug="false" /></system.web></configuration>

    c. Ensure custom error messages are not off.

    <customErrors mode="RemoteOnly"/> or <customErrors mode = "On"/>

    d. Ensure failed request tracing is not enabled.

    – Open IIS.

    – Go to Connections pane, select server connection, site, application or directory.

    – In actions pane, click failed request tracing… make sure the checkbox is not checked.

    e. Configure to use cookies mode for session state in web.config

    <system.web><sessionState cookieless="UseCookies" /></system.web>

    f. Ensure cookies are set with HttpOnly attribute in web.config. This will stop client side script access to cookies.

    <configuration><system.web><httpCookies httpOnlyCookies="true" /></system.web></configuration>

    g. Set global .NET trust level. Open IIS, in the features view, double click .NET Trust Levels.

  10. Request filtering & restrictions in web.config, set maxAllowedContentLength, maxUrl, maxQueryStringallowHighBitCharacters (setting to dis-allow non-ASCII characters) & allowDoubleEscaping.
    <system.webServer><security><requestFiltering allowHighBitCharacters="false" allowDoubleEscaping = "false"><requestLimits maxAllowedContentLength="30000000" maxUrl="4096" maxQueryString="1024" /></requestFiltering></security></system.webServer></configuration>
  11. Disallow unlisted file extensions in web.config.
    <system.webServer><security><requestFiltering><fileExtensions allowUnlisted="false" ><add fileExtension=".asp" allowed="true"/>
    
    <add fileExtension=".aspx" allowed="true"/><add fileExtension=".html" allowed="true"/></fileExtensions></requestFiltering></security></system.webServer></configuration>