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...

Covariance and Contravariance-General Discussion

If you have just started the exploration of .Net Framework 4.0, two terms namely Covariance and Contravariance might have been heard. The concept that these terms encapsulate are used by most developer almost daily, however there has never been any botheration about the terminologies. Now, what actually these terms mean and how are these going to affect us as a developer, if we dive in to the details. The simple answer is it’s always good to know your tools before actually using them. Enough philosophy, let’s get to the business. Starting the discussion let me reiterate that in addition to Covariance and Contravariance, there is another terminology, Invariance. I’ll by start here by diving into the details of Invariance and then proceed further. Invariance: Invariance can be better understood by considering the types in .Net.>net has basically two type, value-types and reference-types. Value types (int, double etc) are invariant i.e. the types can’t be interchanged either ...

Advanced WCF

In this post, I am sharing the link of articles about  advanced topics in WCF. The List of articles is exhaustive and can serve as your repository for all WCF queries. Concurrency,Throttling & Callbacks  WCF Concurrency (Single, Multiple and Re entrant) and Throttling   WCF-Interop and BinarySecurityToken  WCF Callbacks  Creating Web Services From WSDL Link1 Link2 Link3 Link4 WCF-Security WCF over HTTPS   Transport Security(basic)/HTTPS UserNamePasswordValidator ServerCertificateValidationCallback 9 simple steps to enable X.509 certificates on WCF - CodeProject http://www.codeproject.com/KB/WCF/9StepsWCF.aspx?display=Print Message Security(Certificate)/PeerTrust Securing WCF Services with Certificates. - CodeProject http://www.codeproject.com/KB/WCF/wcf_certificates.aspx Message Security(Certificate)/ChainTrust How To Configure WCF Security Using Only X.509 Certificates - CodePr...