Skip to main content

URL Encryption/URL Rewriting

One of the main security checks that the most of the sites implement is URL encryption.
URL encryption in simple terms converts the human readable address into encrypted format. Most of the times only a part of the URL is encrypted that makes it secure by hiding I the inner implementation details used on the page.
Consider an example:
Imagine a page which provides user details and let’s assume that the URL for that is http://[site]/users?user_id=[userid]. The same page is called over and again, just y differing the user_id parameter.
The simplest approach is to encrypt this value so that it becomes hard to guess the user_id and prevent unauthorized access. (Assuming that Role-based security is not used, as provided in ASP.Net).
This looks simple; however one of the side-effects arising out of this could be JavaScript or any code that reads the value from Querysting. To avoid this issue we need to encrypt the page when it is rendered and decrypt the values when there is a need.
Easier said than done; the challenge is to identify when to encrypt and decrypt and what logic to use for encryption and decryption.
Some of the approaches for implementing it, can be found at this location
After reading the above approaches (if you cared to go through the above link), I found the Http Module option the Best that suits the requirement.

However the approach seemed a bit confusing, so let’s tweek it a bit and write an HttpModule that will do the trick for us.
Code :
using System;
using System.IO;
using System.Web;
using System.Text;
using System.Security.Cryptography;

public class URLRewriter : IHttpModule
{

public void Init(HttpApplication context)
{
context.BeginRequest += new EventHandler(context_BeginRequest);
}

private const string param = "enc=";
private const string enc_key = "key";
static string OriginalUrl;
void context_BeginRequest(object sender, EventArgs e)
{
HttpContext context = HttpContext.Current;
if (context.Request.Url.OriginalString.Contains("aspx") && context.Request.RawUrl.Contains("?"))
{
string queryval = GetQuery(context.Request.RawUrl);
string querypath = GetQueryVirtualPath();

if (queryval.StartsWith(param, StringComparison.OrdinalIgnoreCase))
{
// Decrypts the query string and rewrites the path.
string OriginalQuery = queryval.Replace(param, string.Empty);
string decryptedQuery = DecryptURL(OriginalQuery);
context.RewritePath(querypath, string.Empty, decryptedQuery);
}
else if (context.Request.HttpMethod == "GET")
{
// Encrypt the query string and redirects to the encrypted URL.
string encryptedQuery = string.Empty;
encryptedQuery = Encrypt(queryval);
context.Response.Redirect(querypath + encryptedQuery);
}
}
string qrystrng = context.Request.RawUrl;
if (qrystrng.Contains("?"))
{
string[] prntexcp = qrystrng.Split('?');
string query = GetQuery(context.Request.RawUrl);
string path = GetQueryVirtualPath();

if (query.StartsWith(param, StringComparison.OrdinalIgnoreCase))
{
// Decrypts the query string and rewrites the path.
string rawQuery = query.Replace(param, string.Empty);
string decryptedQuery = DecryptURL(rawQuery);
context.RewritePath(path, string.Empty, decryptedQuery);
}
else if (context.Request.HttpMethod == "GET")
{
// Encrypt the query string and redirects to the encrypted URL.
OriginalUrl = path;
string encryptedQuery = string.Empty;
encryptedQuery = Encrypt(query);
context.Response.Redirect(path + encryptedQuery);
}

}

}

private static string GetQueryVirtualPath()
{
string path = HttpContext.Current.Request.RawUrl;
path = path.Substring(0, path.IndexOf("?"));
return path;
}

private static string GetQuery(string url)
{
int index = url.IndexOf("?") + 1;
return url.Substring(index);
}

private string Encrypt(string strEncrypted)
{
try
{
byte[] b = System.Text.ASCIIEncoding.ASCII.GetBytes(strEncrypted);
string encryptedConnectionString = Convert.ToBase64String(b);
return "?" + param + encryptedConnectionString;
}
catch
{
throw;
}
}

private string DecryptURL(string encrString)
{
try
{
byte[] b = Convert.FromBase64String(encrString);
string decryptedConnectionString = System.Text.ASCIIEncoding.ASCII.GetString(b);
return decryptedConnectionString;
}
catch
{
throw;
}
}

#endregion

}

Code Analysis:
URLRewriter class derives from IHttpModule i.e. it is an HTTP Module(for details on HttpModule please visit the link

IT traps the httpRequest and httpResponse and performs the logic( self explanatory) written in code. The Code encrypts the incoming Querysting values in Base64String, that is non readable.
(Another option can be to implement various algorithms (Rjandel etc) that will provide more security.)

The code encrypts the plaintext and decrypts the encrypted string as appropriate.

Shortcomings: This Code will need modifications if URL value is appended to on Client Side (via JavaScript(s))

Scope of Improvement: The above written code can be enhanced to enable/disable conditional logic for the pages as per the requirement

Last step required to make this class usable is to register the Module in Web.config as demonstrated below

<httpModules>
      <add name="URLRewriterMod" type="URLRewriter"/>
 </httpModules>

Advantage:
The main advantage of this class is the fact that if the module is not registered as described above, the code will function as normal(useful in debugging)
I appreciate the efforts put in By Sumit Khandelwal in simplifying the encryption and Decryption methods and making them generic enough to be deployed and used in most common scenarios.
Till Next we connect
Happy Coding!!

Comments

Popular posts from this blog

Asp.Net 4.0: An Overview-Part-III

This is the last post in the series which will explore the following new features of ASP.Net 4.0  Performance Monitoring for Individual Applications in a Single Worker Process Web.config File Refactoring Permanently Redirecting a Page Expanding the Range of Allowable URLs Performance Monitoring for Individual Applications in a Single Worker Process It is a common practice to host multiple ASP.NET applications in a single worker process, In order to increase the number of Web sites that can be hosted on a single server. This practice results in difficulties for server administrators to identify an individual application that is experiencing problems. ASP.NET 4 introduces new resource-monitoring functionality introduced by the CLR. To enable this functionality, following XML configuration snippet is added to the aspnet.config configuration file.(This file is located in the directory where the .NET Framework is installed ) <?xml version="1.0" encoding="UTF-8"

WCF-REST Services-Part-II

HOW REST is implemented in WCF Part-I of the series explored the REST conceptually and this post will explore how REST is implemented in WCF. For REST implementation in WCF, 2 new attributes namely WebGetAttribute and WebInvokeAttribute are introduced in WCF along with a URI template mechanism that enables you to declare the URI and verb to which each method is going to respond. The infrastructure comes in the form of a binding ( WebHttpBinding ) and a behavior ( WebHttpBehavior ) that provide the correct networking stack for using REST. Also, there is some hosting infrastructure help from a custom Service¬Host ( WebServiceHost ) and a ServiceHostFactory ( WebServiceHostFactory ). How WCF Routes messages WCF routes network messages to methods on instances of the classes defined as implementations of the service. Default behavior ( Dispatching ) for WCF is to do this routing based on the concept of action. For this dispatching to work, an action needs to be present in ev

SOLID principles -Code Samples and Free Ebook

I planned to write code samples for SOLID principle implementations, however I am a firm believer of " NOT RE-INVENTING THE WHEEL ", when all you need is use the wheels and make a new CAR. Going by the ideology, I have found an excellent  SOLID principles FREE -Ebook ( covering all aspects of SOLID design principles, with Code sample). This book is an excellent visual aid to remember these principles, as it uses Motivational posters for explaining SOLID design principles. One additional advantage to the above mentioned book is the Code-Refactoring ebook . Both of these books can be downloaded from this EBOOK download Link Both of these books can be downloaded form here. Hope this book proves useful... Till next we connect.... Happy Learning..