IIS Request Filtering19th August 2015
What is Request Filtering?
"Request Filtering is a built-in security feature that was introduced in Internet Information Services (IIS) 7.0, and replaces much of the functionality that was available through the UrlScan add-on for IIS 6.0" from the IIS Site.
Is it worth it?
Let's get one thing straight. Request Filtering is not a cure or a quick fix for insecure code. It is merely part of defence in depth. It might pursuade script-kids to try a different target or to make your site less attractive. If it makes your site that little bit more secure then why not use it? It's free and easy to configure.
Accessing The Feature
You can configure it at server or site level. This allows granular configuration for each site. A WCF service is likley to need a different configuration to an ASP.NET website.
In IIS, double click the Request Filtering icon to open its window.
Before continuing with the configuration, it's worth learning what the side effects of Request Filtering are. You will get errors to start with. For colleagues who are unaware that you have configured Request Filtering will get upset when they start getting unexpected 404s!
Request Filtering works at the beginning of the request pipeline by handling the BeginRequest event. If a filter is matched then a HTTP 404 response occurs with a sub-status code. It will then shortcut the remainder of the pipeline, meaning that blocked requests are ended early. It also means that after configuration you will probably be getting 404 responses, especially if you've been too over zealous with your filters! You will need to test your site(s) to make sure they still work. Ensure that you have IIS logging enabled, you are logging the sc-status and sc-substatus fields. You should also become familiar with the amazing Log Lizard to help you debug.
* 404.5 URL Sequence Denied
* 404.6 Verb Denied
* 404.7 File extension denied
* 404.8 Hidden Namespace
* 404.10 Request Header Too Long
* 404.11 URL Double Escaped
* 404.12 URL Has High Bit Chars
* 404.13 Content Length Too Large
* 404.14 URL Too Long
* 404.15 Query String Too Long
* 404.18 Query String Sequence Denied
* 404.19 Denied by Filtering Rule
Useful Lizard Queries
Blocked File Extensions
EXTRACT_EXTENSION( cs-uri-stem ) AS Extension
WHERE sc-status = 404 and sc-substatus = 7 --file extension denied
ORDER BY Extension DESC
HTTP 404 Sub-Status Descriptions
SELECT sc-status As Status, sc-substatus AS SubStatus,
COUNT(sc-substatus) As SubStatusCount,
WHEN 1 THEN 'Site Not Found'
WHEN 2 THEN 'ISAPI or CGI restriction'
WHEN 3 THEN 'MIME type restriction'
WHEN 4 THEN 'No handler configured'
WHEN 9 THEN 'File attribute hidden'
WHEN 16 THEN 'DAV request sent to the static file handler'
WHEN 17 THEN ' Dynamic content mapped to the static file handler via a wildcard MIME mapping'
WHEN 20 THEN ' Too Many URL Segments'
--5-19 below are Request Filtering
WHEN 5 THEN 'URL Sequence Denied'
WHEN 6 THEN 'Verb Denied'
WHEN 7 THEN 'File extension denied'
WHEN 8 THEN 'Hidden Namespace'
WHEN 10 THEN 'Request Header Too Long'
WHEN 11 THEN 'URL Double Escaped'
WHEN 12 THEN 'URL Has High Bit Chars'
WHEN 13 THEN 'Content Length Too Large'
WHEN 14 THEN 'URL Too Long'
WHEN 15 THEN 'Query String Too Long'
WHEN 18 THEN 'Query String Sequence Denied'
WHEN 19 THEN 'Denied by Filtering Rule'
END AS SubStatusDescription
WHERE sc-status = 404
GROUP BY Status , SubStatus
ORDER BY Status
The User Interface
The UI consists of seven tabs. If you prefer, you can also configure Request Filtering in the web.config of the site or server, but the UI is pretty easy to use.
File Name Extensions Tab
Right-click to add allow or deny strings. You need to know what extensions your site uses. This is where using Log Lizard is useful. You can use the query above to list the file extensions that are requested and add them to the allowed list.
This is where you can filter certain strings if they are found in the URL or QueryString. You can choose the file extensions you want to filter, such as scripton .aspx pages only.
You should consider what strings might be maliciously sent to the site and build an appropriate list of strings to block such as:
- body ...and some others you might want to consider: /* char alter begin cast convert create cursor declare delete drop end exec fetch insert kill open select sys table update alert document cookie xp_ sp_ (but this also maybe overkill, best bet is to try it and then test. Every system is different).
Hidden Segments Tab
This feature allows you to reject requests that contain a URL segment (for example, a folder name such as BIN, App_Data or a particular file such as web.config). Strangely, this is configured with some folders on my work PC out the box without any extra configuration from me, but on my home PC where I'm writing this blog it only lists web.config.
Adding strings onto this tab can help prevent URL-based attacks (such as directory traversal). Denying ".." will remove this chance of an attacker being able to exploit this URL sequence. You may also want to deny ":" which can be used for an alternate data streams attack.
Most sites will use POST and GET which you should allow if appropriate. There are many more which you probably don't use such as OPTIONS. This provides a list of methods supported by the webserver. Useful info for hackers!
Headers are just key/value pairs that define parts of the request and repsonse such as encoding, the dates, server details, etc. Using this tab you can restrict the size of specified headers.
You may know all the querystrings that your site uses, so you could allow them by right clicking and adding allow strings.
Context Menu - Edit Feature Settings
Finally, when right-clicking to see the context menu there is always the option "Edit Feature Settings".
The options are fairly obvious. The request limites will need to be tailored to your particular sites. Bear in mind you may have a file upload feature that would require a max content length of several megabytes. If you need more details then check out the IIS Site.
I hope you find this useful. Strength in depth is a good policy to have!