Background
Today’s world is the world of the internet. Developers build websites using different frameworks, using different technologies. ASP.Net MVC (Model – View – Controller) is one of the powerful frameworks to develop web applications. Nowadays, the internet is a medium where you can do anything like purchasing items, booking tickets, online money transactions etc. So, for every transaction through a website or any message exchange, SECURITY should be very important. Any third person shouldn’t be able to access user’s private/sensible information (could be anything like Passwords, Session IDs, Account Numbers etc.) over HTTP network.
Basically, a website is designed/developed for end users to interact with different web pages, manipulate user data in the form of Request-Response. This Request-Response exchange happens through “HTTP” protocol, and as you all know HTTP is stateless protocol.
Suppose a particular user requested a page (with MVC, a View), server provides that page putting information in HTTP header & forget about that request. But, what if the user again requests for the same page with some data? The server won’t understand the request since, the previous request will be flushed out & server will consider that request, a fresh request.
Introducing HTTP Cookie
To avoid the above situation, ASP.Net MVC has a HTTP Cookie. General definition says, Cookie is a small piece of data sent from a website and stored in the user's web browser while the user is browsing. Cookies are key-value pairs. When developer wants some data to be used for multiple requests with the same user, they use “cookies” with which, the data will be stored on the client side.
In such situation, server sends HTTP header containing the field “Set-Cookie” which holds Key-Value pair with other options to client. Reply to that, client sends request to server along with its own header field which contains name & value of stored cookies to let server know about it. In that case, server will understand that client already has stored cookies, soserver won’t send cookies for next request-response to client unless any changes to cookie values will be there.
Problem
This data stored in client machine. That means, when calling web methods like post and get, all cookie data should be validated. At the same time, you’ll have to ensure that you won’t be storing sensitive information, like passwords, because, cookies are basically text files, anyone can easily pickup those data, modify it, read your sensible information. If the connection between server & client is not over SSL, then it will not be protected from the third-party attackers.
Session cookies are same as any other cookie. But at the server side, that is the only way to have the ID (we consider this as session ID) value, where this ID will be used to fetch data stored on the server. Suppose, third-party attacker senses your data (like ID) via unsecure “HTTP” header which has your cookie information, now he has the ID, so he can send that ID as cookie information with new HTTP header to server. Because of that, server will accept the request & won’t be able to understand whether request come from actual user or from any third-party attacker. Server will assume that as a normal request & will send data related with that ID.
Because attacker sent with new HTTP header, the response comes to that attacker with related information of that ID.
HTTPS with SSL
Before looking into actual solution, if you want the user data to be secured, you have to add SSL certificate & run the website with “HTTPS” protocol.
Solution 1
Adding configuration in web.config
In “web.config”, there are many elements. One of the element called “httpCookies” allows the application to use ReqiresSSL attribute by which, all the transmission of cookies including session will be happened through SSL only. It can also be used inside forms authentication, so if you use SSL for “httpCookies” you must also use it for forms authentication too.
Set the following in Web.config:
- <httpCookies requireSSL="true" />
Like that, set the requireSSL="true" flag for forms Authentication Cookiein the web.config:
- <authentication mode="Forms">
- <forms requireSSL="true" />
- </authentication>
Solution 2
Code change for HttpCookie ASP.Net provides a property to secure the HTTP cookie to be encrypted & send/receive in a secure way. Even if, third person attacks & tries to sense the data in cookie, he won’t be able to decrypt it since the website uses SSL medium.
To do that, we have to set 2 variables& check their values:
- checkSSLEnabled: Set this variable in web.config & check the value.
- checkSecureConn: using “HttpRequest.IsSecureConnection” which indicates whether the HTTP connection uses secure sockets (that is, HTTPS) or not.
Example:
- checkSecureConn = HttpContext.Request.IsSecureConnection;
By checking the combination, you can set the value –
- var userCookie = new HttpCookie(cookieName, sessionID.ToString());
- if (checkSSLEnabled &&checkSecureConn)
- {
- userCookie.Secure = true;
- }
Another Way of Attack URL Manipulation attacks
Now, our website has been secured and SSL enabled running on HTTPS protocol.The developer will now think; our website & all webpages inside the website are secured. Now, there is no threat of attackers, no third party person will sense & access sensitive user data. But attackers have many other ways to access sensible data.
Problem
With “HTTPS” our application does not enforce unencrypted connection for the transmission of the sensitive information such as usernames, passwords or account information. But, it is possible to strip the 'S' from the “https” in the URL and the application will continue to send and receive information without SSL. This has the potential to expose sensitive user information.
Custom Solution for it is to Utilize a secure connection such as HTTP over SSL for the transmission of any sensitive information. Once authenticated, enforce SSL to be utilized for all web pages.
Solution
First, you have to create a class which will bea custom MVC attribute say, “SslRequest” which has to be derived from “
RequireHttpsAttribute” class.
“RequireHttpsAttribute“ class has a method “
OnAuthorization()” whichcalled when a process requests the authorization. Generally, “
OnAuthorization()” method is called when we want to add Custom Authentication (using Forms Auth) and Authorization (Using Role provider).
We have to override this method & then inside it, we have to call “HandleNonHttpsRequest()” method to handle such kind of request. “
HandleNonHttpsRequest()” is a method which handles unsecured HTTP requests that are sent to the action method.
Before that, you have to set & check following 3 flags –
- CheckSSLEnabled – Set this variable in web.config & check the value.
- CheckLocal – using “HttpRequest.IsLocal” which indicates whether the request is from the local computer. The IsLocal property returns true if the IP address of the request originator is 127.0.0.1 or if the IP address of the request is the same as the server's IP address.
- CheckSecureConn – using “HttpRequest.IsSecureConnection” which indicates whether the HTTP connection uses secure sockets (that is, HTTPS).
Code
- public class SslRequest: RequireHttpsAttribute
- {
- public override void OnAuthorization(AuthorizationContext authContext)
- {
- var CheckLocal = authContext.RequestContext.HttpContext.Request.IsLocal;
- var CheckSecureConn = authContext.RequestContext.HttpContext.Request.IsSecureConnection;
-
- if (CheckSSLEnabled && !CheckLocal && !CheckSecureConn)
- {
- HandleNonHttpsRequest(authContext);
- }
- }
- }
In above code, we have created an attribute “SslRequest” which we can use in our MVC application either declare for individual Actions in Controller or declare for entire controller.
Example - [SslRequest]
- public class CustomerController : Controller
- {
- }
In this case, Non-http request will be checked for any action that comes under this controller.
Or,
- public class CustomerController : Controller
- {
- [SslRequest]
- public ActionResult GetProducts(int SessionID)
- {
- }
- }
In this case, Non-http request will only be handled when invoking “GetProducts” Action.
Conclusion
I’ve covered best possible options to transmit cookie data securely via HTTP & also covered the situation when attacks occur through URL manipulations& what would be the solution. I hope you understood how we can achieve security & how we can handle security issues with ASP.Net MVC applications.
I’m going to write another part for the same, in which we will see more scenarios, what more techniques attackers can use to access our web sites. Hope you liked this article.