Filtering for SQL Injection on IIS 7 and later

This article is specific to IIS 7 and later.  If you are using IIS 6.0 or earlier, please see this article.

Starting with version 7.0, IIS has a built-in feature that is able to filter HTTP requests.  If a request is found to have contents deemed unacceptable to the administrator, it will be blocked before it is processed by a web application.  This feature is useful as a mitigation tool in defense of SQL Injection vulnerabilities.

Note that any scheme that filters SQL Injection attempts is only a mitigation.  The complete solution to the problem requires fixing vulnerable web applications.  For more information about SQL Injection vulnerabilities and strategies for fixing them, here are some suggested links:

Definition of SQL Injection
SQL Server Injection Protection
Preventing SQL Injections in ASP
How To: Protect from SQL Injection in ASP.NET
Coding Techniques for protecting against SQL Injection in ASP.NET
Filtering SQL Injection from Classic ASP
Security Vulnerability Research & Defense Blog on SQL Injection Attack

Prerequisite

Before getting started, you should verify the specific version of IIS that you are using.  If you are using SP1 or earlier with IIS 7.0, you will need to install this update to the request filtering component before applying the following configuration.  If you are using IIS 7.0 with SP2, or any later version of IIS, you do not need to install any updates.

Configuring the Request Filter

To create a global filtering rule for SQL Injection:

  • Open the applicationhost.config file in the following path:

%systemroot%\system32\inetsrv\config\applicationhost.config

  • Search the applicationhost.config file for "<requestFiltering>" (without the quotes.)
  • Immediately under the <requestFiltering> tag, paste the following settings:

<filteringRules>
    <filteringRule name="SQLInjection" scanQueryString="true">
        <appliesTo>
            <add fileExtension=".asp" />
            <add fileExtension=".aspx" />
        </appliesTo>
        <denyStrings>
            <add string="--" />
            <add string=";" />
            <add string="/*" />
            <add string="@" />
            <add string="char" />
            <add string="alter" />
            <add string="begin" />
            <add string="cast" />
            <add string="create" />
            <add string="cursor" />
            <add string="declare" />
            <add string="delete" />
            <add string="drop" />
            <add string="end" />
            <add string="exec" />
            <add string="fetch" />
            <add string="insert" />
            <add string="kill" />
            <add string="open" />
            <add string="select" />
            <add string="sys" />
            <add string="table" />
            <add string="update" />
        </denyStrings>
    </filteringRule>
</filteringRules>

  • Save the changes to applicationhost.config.

What effect does this have on my server?

With the above configuration in place, IIS will look at each incoming request for pages with .asp or .aspx extensions to search for specific strings in the request's query string.  If found, IIS will block the request and return a 404 Not Found page to the client.  If you want to change the file extensions, you can add or remove fileExtension tags in the <appliesTo> section.  The specific strings in the search are controlled by the <denyStrings> section.  If you want to change the strings, you can do so by adding or remove entries here.

It is worth noting that the above rule is fairly aggressive about blocking requests.  It is possible that this rule will block legitimate requests.  If this is an issue for your content, it is possible to use a web.config file to create a rule that applies only to content under that web.config.  Do do this, remove any overly restrictive strings from the above applicationhost.config rule.  Then, in the web.config file, include the following configuration with the more restrictive settings in the <system.webServer> section.  For example, if you have content on the server that requires "end" in the query string, remove the <add string="end" /> entry from applicationhost.config and then add the following into the web.config file where you want to restrict "end":

<security>
    <requestFiltering>
        <filteringRules>
            <filteringRule name="SQLInjection2" scanQueryString="true">
                <appliesTo>
                    <add fileExtension=".asp" />
                    <add fileExtension=".aspx" />
                </appliesTo>
                <denyStrings>
                    <add string="end" />
                </denyStrings>
            </filteringRule>
        </filteringRules>
    </requestFiltering>
</security>

Note that the name of the filteringRule tag must be unique and cannot conflict with a name in applicationhost.config or any other web.config files in the path.

Also note that if you want to skip request filtering for all but a specific directory or directories, it is possible to omit the filtering rules in applicationhost.config entirely and just use web.config files to constrain the paths to which filtering applies.

It is also possible to constrain the scope of filtering rules through the use of location tags.

How can I check my logs for SQL Injection attempts?

The request filter logs all of the requests that it blocks in the regular IIS W3SVC logs.  Rejections triggered by a filteringRule will have a status of 404 with a substatus 19.

You can check these logs periodically to see if you've been getting requests with SQL Injection attempts and also to see if your rule may be blocking legitimate requests.

In conclusion

This should be everything that you need to know to get a quick start in filtering SQL Injection attempts on your web server.  For more information about things the request filter can do, check out articles here and here.

Happy request filtering,
-Wade

3 Comments

Comments have been disabled for this content.