Using Enhanced Request Filtering Features in IIS7

Published on September 30, 2008 by sudt

Updated on May 27, 2009 by sudt

Average Rating  Rate It (0)

RSS

This article provides a list of common usage scenarios for enhanced Request Filtering features, which is shipped with Windows Server 2003 SP2 or can be downloaded from http://www.microsoft.com/downloads/ for Windows Server 2008 RTM. In the absence of a corresponding UI to configure these features, appcmd.exe is used to enable and configure the scenarios in this article.

Creating Rules to Disallow String Patterns in Parts of Requests

A new feature, added to IIS Request Filtering feature, is the ability to create a rule list that will let you specify rules to disallow requests based on patterns matched against certain portions of an HTTP request. The main configuration for this is the filteringRules section under the system.webServer/security/requestFiltering section. In the event of a denied condition HTTP Error 404.19 is raised.

Example

In this example a server administrator wishes to block strings “Foo” and “Bar” in header “Foo-Header” using appcmd.exe.
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader'].scanHeaders.[requestHeader='Foo-Header']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader'].denyStrings.[string='Foo']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockFooInHeader'].denyStrings.[string='Bar']"  

Config

<configuration> 
   <system.webServer>
        <security>
            <requestFiltering>
                <filteringRules>
                    <filteringRule name="BlockFooInHeader">
                        <scanHeaders>
                            <add requestHeader="Foo-Header" />
                        </scanHeaders>
                        <denyStrings>
                            <add string="Foo" />
                            <add string="Bar" />
                        </denyStrings>
                    </filteringRule>
                </filteringRules>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

The request below would fail this rule since it has a header called Foo-Header that contains the ‘Foo‘ pattern

GET /iisstart.htm HTTP/1.1\r\n
Host: localhost\r\n
Accept: */*\r\n
Foo-Header: Foo--value\r\n
\r\n

 

Example

 

In this example a server administrator wishes to block strings “Insert” and “Table” in the query string sent with any “.asp” page.


appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True']"


appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True'].appliesTo.[fileExtension='.asp']"

appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True'].denyStrings.[string='Insert']"

appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"filteringRules.[name='BlockSqlCommands',scanQueryString='True'].denyStrings.[string='Table']"

 

Config

 

<configuration>
    <system.webServer>
        <security>
            <requestFiltering>
                <filteringRules>
                   <filteringRule name="BlockSqlCommands" scanQueryString="true">
                        <appliesTo>
                            <add fileExtension=".asp" />
                        </appliesTo>
                        <denyStrings>
                            <add string="Insert" />
                            <add string="Table" />
                        </denyStrings>
                    </filteringRule>
                </filteringRules>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

 

The asp request below would fail this rule since it has string “Insert” in Query String.

GET /iisstart.asp?Query=InsertData HTTP/1.1\r\n
Host: localhost\r\n
Accept: */*\r\n
Foo-Header: Foo--value\r\n
\r\n

It is important to note that the whole header will be scanned for the string patterns listed under “denyString” section and not the header value only.

 

Creating Safe-List for URLs and Query Strings 

This new feature allows you to specify safe URLs and query strings that will bypass all the deny rules defined. This feature must be used with caution, since wrong configuration in this section could let malicious requests bypass your deny rules. If a user always wants to allow the URL ‘/my.login.page.asp’ for instance even though it might trigger a deny rule defined, you can add configuration as below to allow this.The feature can be configured using alwaysAllowedUrls and alwaysAllowedQueryStrings under system.webServer/security/requestFiltering section.

 

Example

 

In the following example appcmd.exe is used to configure page “Login.asp” as a white listed URL and “Allow=true” as a white listed Query string sequence. 
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedUrls.[url='Login.asp']"  

appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"alwaysAllowedQueryStrings.[queryString='Allow=true']"  

Config

<configuration>
    <system.webServer> 
       <security>
            <requestFiltering>
                <alwaysAllowedUrls>
                    <add url="Login.asp" />
                </alwaysAllowedUrls>
                <alwaysAllowedQueryStrings>
                    <add queryString="Allow=true" />
                </alwaysAllowedQueryStrings>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

It is important to note that the leading ‘/’ is required for the URL to be accepted as a valid URL. If a user wants to allow a query string ‘session<1’ which might otherwise trigger a deny rule defined, you can add configuration as below to allow this.Note that you do not need to specify query strings leading with the ‘?’ character.

Creating a Deny List of URL Sequences



To deny a list of URL sequences for all requests create a denyQueryStringSequences section and add the list of strings you want to disallow in the URL of your requests. The deny list is case insensitive and allows encoded values of the format %XX, where XX are hexadecimal digits.In the event of a denied condition HTTP Error 404.18 is raised.

Example

For example, if you wanted to deny any URL with “..” or “./” sequence, appcmd.exe command will be 

appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"denyQueryStringSequences.[sequence='..']"
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /+"denyQueryStringSequences.[sequence='./']"

Config


<configuration>
    <system.webServer>
        <security>
            <requestFiltering>
                <denyQueryStringSequences>
                    <add sequence=".." />
                    <add sequence="./" />
                </denyQueryStringSequences>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

The request below would fail this rule since it has a “..” in its Query String

GET /iisstart.htm?.. HTTP/1.1\r\n
Host: localhost\r\n
Accept: */*\r\n
\r\n

 

Checking for both Escaped and unEscaped Query String 

StringIt is possible that you want to scan for both escaped and un-escaped versions of this pattern using unescapeQueryString attribute in the  “system.webServer/security/requestFiltering” section.

 

Example

 

So if someone were to send a request like http://www.foo.com/id=%3C%53%43%52%49%50%54%3E where the <script> sequence has been escaped, we would like to check the un-escaped version of this query string as well.
appcmd.exe set config "Default Web Site" -section:system.webServer/security/requestFiltering /unescapeQueryString:"True" 

Config

<configuration>
    <system.webServer>
        <security>
            <requestFiltering unescapeQueryString="true">
                <denyQueryStringSequences>
                    <add sequence="script" />
                </denyQueryStringSequences>
            </requestFiltering>
        </security>
    </system.webServer>
</configuration>

 

This will perform 2 passes when it checks for patterns in query string, one for raw query string and one for the un-escaped query string.

Related Content

Comments

  1. Submitted on May 18 2009 by
    lextm
    Please note that such Enhanced Request Filtering is only available from pre-release Windows 7 builds and Windows Server 2008 R2 builds at this moment.

    Windows Vista/Windows Server 2008 does not yet have such a feature.
  2. Submitted on Jul 05 2009 by
    carehart
    The opening sentence refers to the "enhanced Request Filtering features, which is shipped with Windows Server 2003 SP2". Aren't these only in IIS 7? If so, we can't use this in 2003 can we?

You must Log In to comment.