Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

HTTP Request Query String Protection

4.44/5 (29 votes)
9 Feb 2008CPOL4 min read 1   909  
Add one layer of security to your Web application

Table of Contents

  1. Introduction
  2. The Motivation
  3. TagSinj Intervention
  4. Overview of Functionality
  5. The Actual Code Behind It
  6. Using the Code
  7. Comments

Introduction

This article will present a solid method of securing your query string from SQL injections. The overall idea was inspired from the way payment gateways secure their parameters.

TagSinj (Stands for Tag Secure Injection) class includes two main functions which can integrate easily with all Web applications.

The Motivation...

When building applications, it is very necessary to secure the way you grab parameters sent by the HTTP query string. It is very common and simplistic for users just to alter those parameters and mess up your application. For example, let's say you are using two parameters in your query string, one to identify the page you wish to load, and another to load a specific product using its ID (Database ID, i.e.: Primary Key), your query string might look as follows:

http://www.yourdomain.com/default.aspx?page=products&id=234

Let's say you are grabbing those parameters and generating a database query. Your database query might look like this:

SQL
SELECT * FROM product WHERE ProductID = '234'

A simple manipulation of the query string is as follows (removing the value of the parameter "id"):

http://www.yourdomain.com/default.aspx?page=products&id=

Your dynamically generated database query will turn out to be:

SQL
SELECT * FROM product WHERE ProductID = '' 

That usually won't do much harm, except that it wouldn't load properly by the user, but what if your environment is not secured enough? For example:

http://www.yourdomain.com/default.aspx?page=products&id=';DROP DATABASE databasename;--

Your dynamically generated database query will turn out to be:

SQL
SELECT * FROM product WHERE ProductID = '';DROP DATABASE databasename;--'

This can be quite harmful...

TagSinj Intervention

TagSinj intervenes just one layer prior to generating your database query string. Once your page loads, TagSinj will check the sent parameters. If they are authentic, then you can continue executing your code, otherwise, they have been manipulated. You can break execution of the code and handle the exception accordingly.

Overview of Functionality

The main concept behind this idea is mainly to confirm that the parameters that were sent from one page are exactly the same as the parameters received by the recipient page (Works fine, even if both pages are the same page).
To do so, this class will append an additional parameter to the querystring (called "mac") which is an MD5 string (The mac parameter is the MD5 result of all parameters concatenated together with a Secure Access code).

Thus, in order to lock your query string from injections, you would need to generate secure links (generateSecureLink(string link)) and upon loading the page, you need a method to authenticate the parameters (validateLink(HttpRequest Request)).

The Actual Code Behind It...

First, I will discuss the method that generates the secure links. What this method would do is take the original link that you use, for example: default.aspx?par1=hello&par2=world and return default.aspx?par1=hello&par2=world&mac=MD5STRING where MD5STRING is your par1 value concatenated with your par2 value concatenated with your secure access key, i.e. in this case we would have (and if our access code is "howareyou"): helloworldhowareyou.

C#
/// <summary>
/// This method takes a link and appends to it the secure hash used to
/// validate the query string
/// </summary>
/// <param name="""""link""""" />link</param>
/// <returns>input link with mac paramater appended</returns>
        public static string generateSecureLink(string link)
        {
            string toHash = "";
            string[] querystring = null;
            string[] vars = null;
            string[] vals = null;
//if the link has some parameters            
if (link.Contains("?"))
            {
                querystring = link.Split('?'); vars = querystring[1].Split('&');
                foreach (string st in vars)
                {
                    vals = st.Split('=');
                    //toHash has all parameters value appended next to each other
                    toHash += vals[1].ToString();
                }
            }
            //otherwise
            else
            {
                querystring = link.Split('?');
                vars = querystring[1].Split('=');
                toHash += vals[1].ToString();
            }
            //append the access code to the end of the string and MD5 the result
            string hashed = TagSinj.Hash(toHash + TagSinj.AccessCode);
            //returns the mac parameter appended to the link
            return link + "&mac=" + hashed;
        }

Secondly, you would need a method that validates the generated secure link (it is to be used whenever you want to validate that your query string is received exactly the same way that it was sent.

This method takes the HttpRequest (uses the querystring from it). It basically retakes all parameters passed by the querystring except for the "mac", re-concatenates them in the same order they were passed and appends the access key.

Then it matches the resulting MD5 string with the grabbed MD5 string. If both match, then the query string is safe, otherwise it has been manipulated and there is a possible threat.

C#
/// <summary>
/// This method takes an HttpRequest as a parameter and checks 
/// whether the query string parameters have been
/// manipulated by the user
/// </summary>
/// <param name="""""Request""""" />
/// HttpRequest, used to take the querystring item</param>
/// <returns>true if query string is authentic, false otherwise</returns>
public static bool validateLink(HttpRequest Request)
{
    try
    {
        //loop through all the parameters and recreate the hash
        if (Request.QueryString.Count > 0)
        {
            String[] queryKeys = Request.QueryString.AllKeys;
            int queryCount = Request.QueryString.Count;

            string toHash = "";
            for (int m = 0; m < queryCount; m++)
            {
                if (queryKeys[m] != "mac")
                {
                    toHash += Request.QueryString[queryKeys[m]];
                }
            }
            string hashed = TagSinj.Hash(toHash + TagSinj.AccessCode);
            if (hashed != Request.QueryString["mac"])
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        else
        {
            return false;
        }
    }
    catch
    {
        return false;
    }
}

Using the Code

Below, I will illustrate the way to use this class:

Step 1: Include

  • Download TagSinj.zip
  • Add the *.dll file as a reference in your project
  • Include the file in your *.cs files:
C#
using System.Web.UI.WebControls; 
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using TagSinj;

Once the above step has been taken care of, you can now use the two methods offered by this class.

Step 2: Setting up the Access Code

To have a unique "mac" you have to set a value to your access code. This can be set once in your global.asax page or in the page where you are using this class. The access code can be any string of your choice.

//The below selected access code is for illustration purposes only
//Simpler or more complex codes can be randomly generated
TagSinj.TagSinj.AccessCode = "AV$%990LK_12";

Step 3: Generating Secure Links

In order for the query string to be accepted by your application, you have to generate secure links using:

C#
//the generateSecureLink function will append to the parameter added a
//"mac" parameter which will be a unique way of identifying your
//sequence of parameters
secureLink = TagSinj.TagSinj.generateSecureLink
	("anyPage.aspx?var=test1&var1=test2&var2=test3");
Your resulting value should look like: 
anyPage.aspx?var=test1&var1=test2&var2=test3&mac=bc2d6cb550c88bed381521bea654ea11

Step 4: Grabbing Your Variables

Now that you have your links secured, it is time to make sure that no one is manipulating your query string. To do so, under the Page_Load event, add this piece of code:

C#
if (TagSinj.TagSinj.validateLink(this.Request))
{
   //parameters are exactly the same way you have sent them
   //Do action
   Response.Write("The parameters are correct");
}
else
{
   //somebody is playing around with the parameters
   //Do action
   Response.Write("The parameters are incorrect");
}
Conclusion

This way, you have made sure that the parameters that you have sent from one page are exactly the same as the parameters you have received. This functionality will greatly reduce to the point of eliminating the threat of SQL injections to your website.

Comments

This is my first article here at The Code Project. Any comments would be appreciated. Drop me an email if you are planning to use this DLL.
Thank you for reading.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)