Query string encryption for ASP.NET






3.90/5 (28 votes)
Clear text query strings are a potential security threat for your web application. Thus, query strings should always be encrypted.
Introduction
Using query strings to send data from the browser to the server is a widespread approach. Giving the visitor of a web application the opportunity of modifying query strings by transmitting them in clear text, is certainly a potential security threat.
Thus, I encourage developers to encrypt query strings, even if they do not contain confidential data. However, I am aware that it is still possible to alternate an encrypted query string, but with an appropriate exception handling, this is harmless.
Background
To keep this article simple, I used a contradictable encryption (DES encoding), though any cutting-edge encryption can be easily applied to the samples given.
Using the code
So, let's get down to business. The main part of the presented solution consists of a HttpModule
which decrypts the query string and hence provides the page request with the ordinary unencrypted query strings:
using System; using System.Web; using System.Web.Configuration; namespace HelveticSolutions.QueryStringEncryption { /// <summary> /// Http module that handles encrypted query strings. /// </summary> public class CryptoQueryStringUrlRemapper : IHttpModule { #region IHttpModule Members /// <summary> /// Initialize the http module. /// </summary> /// <param name="application">Application, /// that called this module.</param> public void Init(HttpApplication application) { // Attach the acquire request state event // to catch the encrypted query string application.AcquireRequestState += application_AcquireRequestState; } public void Dispose() {} #endregion /// <summary> /// Event, that is called when the application acquires the request state. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void application_AcquireRequestState(object sender, EventArgs e) { // Get http context from the caller. HttpApplication application = (HttpApplication) sender; HttpContext context = application.Context; // Check for encrypted query string string encryptedQueryString = context.Request.QueryString["request"]; if (!string.IsNullOrEmpty(encryptedQueryString)) { // Decrypt query strings string cryptoKey = WebConfigurationManager.AppSettings["CryptoKey"]; string decryptedQueryString = CryptoQueryStringHandler.DecryptQueryStrings(encryptedQueryString, cryptoKey); context.Server.Transfer( context.Request.AppRelativeCurrentExecutionFilePath + "?" + decryptedQueryString); } } } }
As you might have noticed, if there is an encrypted query string for the current request, the module automatically terminates the execution of the current page and internally starts execution of a new request on the server.
The next step is to register the HttpModule
in the web.config file:
<httpModules> <add name="CryptoQueryStringUrlRemapper" type="HelveticSolutions.QueryStringEncryption.CryptoQueryStringUrlRemapper"/> </httpModules>
Last but not least, do not forget to encrypt query strings before sending them back to the server:
private void PrepareSendButton() { NameValueCollection queryStrings = new NameValueCollection(); queryStrings.Add("param1", "Test1"); queryStrings.Add("param2", "Test2"); queryStrings.Add("param3", "Test3"); // Encrypt query strings string encryptedString = CryptoQueryStringHandler.EncryptQueryStrings( queryStrings, WebConfigurationManager.AppSettings["CryptoKey"]); btnSendParams.PostBackUrl = string.Concat("~/Default.aspx?", encryptedString); }
As outlined earlier in this article, the encryption class can be easily replaced by any other encryption class. A full running sample can be downloaded above.
Important issue
The method DecryptQueryStrings
in the CryptoQueryStringHandler
contains the following line :
return Encryption64.Decrypt(encryptedStrings.Replace(" ", "+"), key);
For unknown reasons, the request replaces every '+' character in the query with an empty character.
History
- 30.04.2008 - First version (deleted -> was not possible to modify, why ever...).
- 01.05.2008 - Re-released updated article.
- 08.05.2008 -
BeginRequest
event in theHttpModule
changed toAcquireRequestState
in order to support Session data. - 11th November 2014 - Namespace corrected