Remove Query String Parameter Using the IIS url-rewrite Module

Table of Contents

This is a 8 minute read.

Problem definition

In this article we’ll discuss implementing a set of re-write rules in the IIS url-rewrite module in order to selectively remove a query string parameter.

Why might we want to remove a querystring parameter? 

Well, sometimes in development we may include options that are useful for developers, and probably have code surrounding them to prevent their use in production. However, if we remove the ability for the option to traverse the infrastructure in the first place, we provide a bolstered security posture. It is another layer of protection against mistakes or nefarious requests from being received by the code in production.

Another scenarios could be a 3rd party black box product where we have no control of the output and need to manipulate the query string contents in order to fix an issue or enhancing security by moving data from the query string to the HTTP headers in order to shield the data.

We’re working on Windows Server 2016R2 for this article.

Install the url-rewrite Module

Assuming you already have IIS installed, you will need to install the rewrite module.

Download and run the installer to install the Microsoft IIS url-rewrite module:

https://www.iis.net/downloads/microsoft/url-rewrite

When the rewrite module is installed, you will see the URL Rewrite module in the IIS section of the website’s IIS Management page.

url-rewrite

Configuring the url-rewrite Module

HTTP queries consist of a protocol, domain, path and query string. For example, take the URL:

https://example.com/api/login?testing=true&realm=dev

This is constructed of 4 discrete elements:

Protocol
Domain
Path
Query string
https://
example.com
/api/login
testing=true&realm=dev
The query string is the text that appears after the question mark at the end of the path. It is an ampersand-separated list of url-encoded key/value pairs. In the IIS Management application select the website you want to make the changes to and double click the URL Rewrite module icon under the IIS section.
url-rewrite

Click Add Rule(s)… to start adding a rule and select Inbound – Blank Rule.

Remove Query String Parameter

Name the rule as something useful like RemoveTestingQueryStringOption or similar.

The Regular Expression we’re going to use is a bit fancy-looking. The important bit here is that you update the testing text to be the same as the parameter name that you want to remove.

The default options should be set:

  • Requested URL: Matches the Pattern
  • Using: Regular expressions

The Match URL should match all URLs and we will use the conditions section to determine whether or not we use rewrite anything. The URL is the path section of the request. It doesn’t contain what we’re looking to match.

  • Pattern: (.*) 

Expand the Conditions section and keep the default settings:

  • Logical Grouping: Match All

Click Add, make sure the following settings are set:

  • Condition input: {QUERY_STRING}
  • Check if input string: Matches the Pattern

For the Pattern, use the following regular expression, but replace testing with the required query string parameter you want to remove.

				
					(.*)(testing=(((?!&).)*))(&?)(.*)
				
			

Click OK to finish adding the rule.

In the Action section for the rewrite rule set the following:

  • Append query string: UNCHECKED
  • Rewrite URL: {R:1}?{C:1}{C:6}

Make sure the Append query string option is unchecked because we have re-written the complete request, including a modified query string.

Finally, make sure the Stop processing of subsequent rules is UNCHECKED. This rule needs some following rules in order to clean up the request URL if it has been rewritten.

Click Apply on the right hand side of the dialog.

Remove Trailing Ampersand

Under certain conditions, a trailing ampersand is left on the request URL even so you can end up with invalid requests such as https://example.com/api/login?realm=dev& which may cause some software to produce an error. This happens when the first rule removes the query string parameter from the end of the parameter string.

Add another rewrite rule, and again start with a blank rule.

Again, the Match URL will match all requests:

  • Pattern: (.*)

Add the following condition:

  • Condition input: {QUERY_STRING}
  • Check if input string: Matches the Pattern
  • Pattern: (.*)&$

In the Action group set the following options:

  • Action type: Rewrite
  • Rewrite URL: {R:0}?{C:1}
  • Append query string: UNCHECKED

Finally set:

  • Stop processing of subsequent rules: UNCHECKED

Click Apply on the right hand side and then click Back to Rules.

Remove Trailing Question Mark

The final glitch from the first rewrite is that, if the parameter we’re trying to remove is the only parameter in the query string we’ll end up with a trailing question mark in the request after the initial rewrite. Again, this should be removed to make sure any on-ward processing of the request doesn’t generate errors. We need to detect when the request has an empty {QUERY_STRING} AND the complete request ends in a question mark.

Add another rewrite rule, and again start with a blank rule.

Again, the Match URL will match all requests:

  • Pattern: (.*)

Add the following condition:

  • Condition input: {QUERY_STRING}
  • Check if input string: Matches the Pattern
  • Pattern: ^$

In the Action group set the following options:

  • Action type: Rewrite
  • Rewrite URL: {R:0}?{C:1}
  • Append query string: UNCHECKED

Finally set:

  • Stop processing of subsequent rules: UNCHECKED

Click Apply on the right hand side and then click Back to Rules.

Complete web.config Configuration

Although the instructions above show the UI method for configuring the website, this results in the a web.config file being written to the file root of the website.

Here’s the web.config that you can copy and paste in place to get up and running more quickly…

				
					
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="RemovTestingQueryStringParameter">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{QUERY_STRING}" pattern="(.*)(testing=(((?!&amp;).)*))(&amp;?)(.*)" />
                    </conditions>
                    <action type="Rewrite" url="{R:1}?{C:1}{C:6}" appendQueryString="false" />
                </rule>
                <rule name="RemoveTrailingAmpersand">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{QUERY_STRING}" pattern="(.*)&amp;$" />
                    </conditions>
                    <action type="Rewrite" url="{R:0}?{C:1}" appendQueryString="false" />
                </rule>
                <rule name="RemoveTrailingQuestionmark">
                    <match url="(.*)" />
                    <conditions>
                        <add input="{QUERY_STRING}" pattern="^$" />
                    </conditions>
                    <action type="Rewrite" url="{R:1}" appendQueryString="false" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>
				
			

Testing

NOTE: This section can be performed if you have ASP enabled on the website.

Using a simple aspx page we can test that the URL rewrite is working OK. We only work on the querystring. The following code can be pasted into a file called index.aspx (or whatever suits your website) as a test page to see what request hits the web page with the rewrite rules in place:

				
					
<%
Response.Write("<p><b>QUERY_STRING</b> <code>" & Request("QUERY_STRING") & "</code></p>")
Response.Write("<p><b>URL</b> <code>" & Request("URL") & "</code></p>")
Response.Write("<p><b>HTTP_X_ORIGINAL_URL</b> <code>" & Request("HTTP_X_ORIGINAL_URL") & "</code></p>")
%>
				
			

Now, we can call the website with different query strings in order to test all situations we might come across. The query parameter can appear anywhere in amongst other parameters:

If you don’t want to enable ASP, you can use Microsoft’s ARR proxy server module to forward the requests on to another server where you can inspect requests.

Finishing up

So to wrap up, we covered off installing and configuring the IIS url-rewrite module with a regular expressions and  corresponding actions in order to remove some query string parameters, as well as some simple pages to validate the correct operation of the rules. 

For more information on the rewrite rule syntax and options, see the documentation for the url-rewrite module.

As always, we hope that this is useful to the wider community. 

Leave a Reply

Your email address will not be published. Required fields are marked *