Blocking SQL injection using IIS URL Rewrite

We have had quite a few conversations about SQL injection on my blog, including Filtering SQL Injection from Classic ASP and Using Rules Configuration in UrlScan 3.0 to filter SQL injection. One of the shortcomings that we talked about was that UrlScan is not as flexible as some users want it to be since it does not have the ability to use regular expressions. Well the story changes quite a bit with IIS URL Rewrite module, that is capable of doing request and response rewriting based on regular expressions. For those weighing between URL Rewrite and UrlScan, URL Rewrite has more flexibility but UrlScan is a lot more performant, so choose depending on your needs and resources.

I have seen a lot of articles crop up with increasingly complex and voluminous rules for this, so I wanted to present something a little more simplified for folks to use. Thanks to Bala from the SQL Server Security team (who has written excellent MSDN documentation on preventing SQL injections in ASP) there is a simpler rule to use that will catch quite a few of the variants without any false positives for any valid requests that I have seen so far. Most of the widespread automated SQL injection attacks use a DECLARE->CAST->EXEC approach to executing their injection. If I were to just put 'CAST' in a deny list I would hit a lot of false-positives, e.g. if my Url contained the word 'casting'.By requiring a Declare ... Cast ... Exec structure we can drastically reduce the chances of a false-positive.

Here is the Regular Expression used:

[dD][\%]*[eE][\%]*[cC][\%]*[lL][\%]*[aA][\%]*[rR][\%]*[eE][\s\S]*[@][a-zA-Z0-9_]+[\s\S]*[nN]*[\%]*[vV][\%]*[aA][\%]*[rR][\%]*[cC][\%]*[hH][\%]*[aA][\%]*[rR][\s\S]*[eE][\%]*[xX][\%]*[eE][\%]*[cC][\s\S]*

Notice the the groupings in the brackets towards the beginning spell out DECLARE and that towards the end spell out EXEC. That should give you a good idea of how this regex is expected to work. To add this validation to the REQUEST_URI you could use configuration like that below in a web.config file.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
   
<system.webServer>
       
<rewrite>
           
<rules>
               
<rule name="Filter SQL injection" stopProcessing="true">
                   
<match url=".*" />
                    <
conditions>
                       
<add input="{REQUEST_URI}" pattern="[dD][\%]*[eE][\%]*[cC][\%]*[lL][\%]*[aA][\%]*[rR][\%]*[eE][\s\S]*[@][a-zA-Z0-9_]+[\s\S]*[nN]*[\%]*[vV][\%]*[aA][\%]*[rR][\%]*[cC][\%]*[hH][\%]*[aA][\%]*[rR][\s\S]*[eE][\%]*[xX][\%]*[eE][\%]*[cC][\s\S]*" />
                    </
conditions>
                   
<action type="AbortRequest" />
                </
rule>
           
</rules>
       
</rewrite>
   
</system.webServer>
</configuration>

You can change the <match url> directive above to \.as[p|px] if you want to apply the filtering rule to .asp and .aspx pages only.

Update: The SQL server security team has a more detailed blog entry on this that you can refer to.

4 Comments

  • Will this work for posts also?

  • This is a nice followup article to the URLScan ones regarding SQL injection that we chatted at length about.

    Still I find the regular expression really confusing and non-user friendly. If I was presented with a RegX like that it would take me an age to work out.

    Looks like I might have to learn more of it as nothing will happen with new versions of URL scan. Multiple terms groups would be good.

    If the url contains all the terms
    DECLARE CAST EXECUTE
    (or these terms in that order)
    etc would be a much more user friendly of admin using it.

    I fear very few admin will actually use these regXs as they are so complex.

    Even looking at that RegX:

    [dD][\%]*[eE][\%]*[cC][\%]*[lL][\%]*[aA][\%]*[rR][\%]*[eE][\s\S]*[@][a-zA-Z0-9_]+[\s\S]*[nN]*[\%]*[vV][\%]*[aA][\%]*[rR][\%]*[cC][\%]*[hH][\%]*[aA][\%]*[rR][\s\S]*[eE][\%]*[xX][\%]*[eE][\%]*[cC][\s\S]*

    I cannot see where the word CAST in there. I thought that the article would stop when the words DECLARE CAST EXEC appeared in the order. I need to go back to school with RegEx if I decide to use it.

  • @Rovastar
    Regex is difficult to read, but it does offer the most flexibility and control. We definitely could try adding more templates in our UI to make authoring rules easier. We have already done some work in this area with the UrlRewrite UI and we will keep expanding on that.

  • Cheers Nazim.

    True you have a lot of flexability and control, I fully understand that. I look foward to more work on the UI side for this.

Comments have been disabled for this content.