title: Using IIS url rewrite to protect against SQL injection
body: <p>We use a variety of CMS (Wordpress, Joomla) on our server and therefore a lot of the code is third-party so we have no control over quality. Whilst we always keep everything up-to-date we recently had a website that was hacked.</p>
  
  <p>To try and prevent this from happening in the future i've added the URL rewrite rules into web.config files. But I have a couple of questions:</p>
  
  <ol>
  <li><p>Should I use RequestFiltering instead of Query_String to detect injections? Or is there no difference?</p></li>
  <li><p>Is web.config cached by IIS or is it like Apache .htaccess and queried on every single request? If so, will this be a performance drain?</p></li>
  <li><p>Have I missed any possible attacks?</p></li>
  </ol>
  
  <p>CODE...</p>
  
  <pre><code>&lt;rule name="Injection Blocking"&gt;
       &lt;match url="^(.*)$" ignoreCase="false" /&gt;
       &lt;conditions logicalGrouping="MatchAny"&gt;
         &lt;add input="{HTTP_USER_AGENT}" pattern="(havij|libwww-perl|wget|python|nikto|curl|scan|java|winhttp|clshttp|loader)" /&gt;
         &lt;add input="{HTTP_USER_AGENT}" pattern="(%0A|%0D|%27|%3C|%3E|%00)" /&gt;
         &lt;add input="{HTTP_USER_AGENT}" pattern="(;|&amp;lt;|&gt;|'|&amp;quot;|\)|\(|%0A|%0D|%22|%27|%28|%3C|%3E|%00).*(libwww-perl|wget|python|nikto|curl|scan|java|winhttp|HTTrack|clshttp|archiver|loader|email|harvest|extract|grab|miner)" /&gt;
         &lt;add input="{THE_REQUEST}" pattern="(\?|\*|%2a)+(%20+|\\s+|%20+\\s+|\\s+%20+|\\s+%20+\\s+)HTTP(:/|/)" /&gt;
         &lt;add input="{THE_REQUEST}" pattern="etc/passwd" /&gt;
         &lt;add input="{THE_REQUEST}" pattern="cgi-bin" /&gt;
         &lt;add input="{THE_REQUEST}" pattern="(%0A|%0D|\\r|\\n)" /&gt;
         &lt;add input="{URL}" pattern="owssvr\.dll" /&gt;
         &lt;add input="{HTTP_REFERER}" pattern="(%0A|%0D|%27|%3C|%3E|%00)" /&gt;
         &lt;add input="{HTTP_REFERER}" pattern="\.opendirviewer\." /&gt;
         &lt;add input="{HTTP_REFERER}" pattern="users\.skynet\.be.*" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="[a-zA-Z0-9_]=http://" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="[a-zA-Z0-9_]=(\.\.//?)+" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="[a-zA-Z0-9_]=/([a-z0-9_.]//?)+" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="\=PHP[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(\.\./|%2e%2e%2f|%2e%2e/|\.\.%2f|%2e\.%2f|%2e\./|\.%2e%2f|\.%2e/)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="ftp\:" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="http\:" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="https\:" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="\=\|w\|" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="^(.*)/self/(.*)$" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="^(.*)cPath=http://(.*)$" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(\&amp;lt;|%3C).*script.*(\&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(&amp;lt;|%3C)([^s]*s)+cript.*(&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(\&amp;lt;|%3C).*embed.*(\&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(&amp;lt;|%3C)([^e]*e)+mbed.*(&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(\&amp;lt;|%3C).*object.*(\&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(&amp;lt;|%3C)([^o]*o)+bject.*(&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(\&amp;lt;|%3C).*iframe.*(\&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(&amp;lt;|%3C)([^i]*i)+frame.*(&gt;|%3E)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="base64_encode.*\(.*\)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="base64_(en|de)code[^(]*\([^)]*\)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="GLOBALS(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="_REQUEST(=|\[|\%[0-9A-Z]{0,2})" ignoreCase="false" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="^.*(\(|\)|&amp;lt;|&gt;|%3c|%3e).*" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="^.*(\x00|\x04|\x08|\x0d|\x1b|\x20|\x3c|\x3e|\x7f).*" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(NULL|OUTFILE|LOAD_FILE)" ignoreCase="false" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(\.{1,}/)+(motd|etc|bin)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(localhost|loopback|127\.0\.0\.1)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(&amp;lt;|&gt;|'|%0A|%0D|%27|%3C|%3E|%00)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="concat[^\(]*\(" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="union([^s]*s)+elect" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="union([^a]*a)+ll([^s]*s)+elect" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="\-[sdcr].*(allow_url_include|allow_url_fopen|safe_mode|disable_functions|auto_prepend_file)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(;|&amp;lt;|&gt;|'|&amp;quot;|\)|%0A|%0D|%22|%27|%3C|%3E|%00).*(/\*|union|select|insert|drop|delete|update|cast|create|char|convert|alter|declare|order|script|set|md5|benchmark|encode)" /&gt;
         &lt;add input="{QUERY_STRING}" pattern="(sp_executesql)" /&gt;
      &lt;/conditions&gt;
     &lt;action type="CustomResponse" statusCode="403" statusReason="Forbidden" statusDescription="Forbidden" /&gt;
  &lt;/rule&gt;
  </code></pre>