Home
    Shop
    Advertise
    Write For Us
    Affiliate
    Newsletter
    Contact

ASP.NET Session State Security

To communicate with visitors, ASP.NET website uses HTTP protocol. HTTP is stateless protocol which means that web server doesn't know if two requests come from the same visitor or from two different visitors. Information like browser type, operating system, IP address etc., are all unreliable to separate visitors and can't be used for identification. In fact, only information used by ASP.NET to recognize individual visitor is session ID.

 

Session ID is a string, stored in cookie on client's computer, or in case of cookieless sessions inside of URL. In both cases session id is just a plain string stored without encryption. So, anyone who read that string can use it to make request to same website from other computer and on that way will get access to information stored in session state.

How session id could be stolen

Getting session id's from others could be security problem if website is storing any sensitive data in session object. In that case, malicious user will be recognized as regular visitor and will possibly see private data. Three main methods how malicious visitor could obtain session id of other visitor are:

1. Attacker read TCP packet somewhere between server and user's computer. To prevent this, you can use secure HTTPS protocol and SSL connection to encrypt communication between browser and server.

2. Virus is installed on victim's computer. In this case, virus can read cookies and currently opened URLs and send data to attacker. It is harder for you to protect visitor in this case even in intranet, but especially on Internet where you don't have access to visitor's machine. To increase security, you can save visitor's data like IP address, browser type, OS type etc., when he or she makes first request. Then, for every next request, compare these data and if they are not equal, consider it as attack. Probably best place to perform this check is inside Application_BeginRequest procedure in Global.asax.

3. Using cross side scripting, attacker will try to execute malicious JavaScript, which will read regular visitor's session cookie or current URL, and finally send gathered session id string to attacker's computer or some other server. To prevent cross side scripting attacks, validate using server side code every input from users; like text box values, query strings, cookies values etc. Remove potentially dangerous HTML tags as <script>, <frame>, <iframe> and so on. Possibly, you can use Server.HtmlEncode method when display user's input in Label control or write it on page using Response.Write method.

Security issues when State Server is used

Using of State Server as storage for session data is more reliable and scalable option than default InProc mode. Sessions stored in State Server are stored out of web application's process. Because of that, session variables are not deleted if web application restarts. Also, if dedicated State Server is used, web server's memory remains free which increases performances.

Note that, by default, State Server is open to all computers in network. That means that you should restrict access to computer which is running state server, especially disable access from Internet. Allow only connections from web servers in web farm which actually use State Service and restrict everyone else.

For additional security, change default 42424 port to some other port number. Also, you can think about encrypting of connection string to state server in web.config. More about using and configuring of Session State you can read in How to Store Session Data in ASP.NET State Server tutorial.

Security issues when SQL Server session provider is used

SQL Server is one more out-of-process option. This mode stores session data in SQL Server database. If SQL Server works in cluster, this is most reliable place to store session state.

There are also security problems which are specific to SQL Server. If attacker gets access to SQL Server, it is possible to read session data using simple SQL queries.

So, do security recommendations like for any other database driven application:

- encrypt connection string in web.config
- if possible, restrict access from Internet for SQL Server machine.
- use Windows authentication to connect and disable SQL Server authentication. On this way passwords will not travel through network.

More about how to set up and use SQL Server as storage for session data, you can find in How to store ASP.NET session state on SQL Server tutorial.

Using of cookieless session is security problem

As said earlier, HTTP as stateless protocol and doesn't recognize individual visitors. ASP.NET uses generated string, named session id and stored in a cookie on visitor's computer. Session id string should be unique to each visitor. Then, on every request, ASP.NET reads session id from cookie and compare it with existing session ids on server side. If some session id saved on server side is equal to received visitor's session id, ASP.NET connects that visitor with appropriate collection of session variables.

So, if attacker make request using session id of certain visitor, ASP.NET will "think" that both requests are from same visitor and attacker will share same session data as regular visitor. If session data are sensitive, this could be serious security problem. Fortunately, session id is complex string, so it is unlikely that attacker will guess other's session id or succeed using brute force.

By default session id is stored in cookie. But, if cookieless session is used session id is stored in URL. In this case, it is much easier for attacker to find other's session id. Cookieless session is defined in web.config with line like this:

<sessionState cookieless="UseUri" />

Now, all URLs will have embedded session id. For example:

http://mappoint.msn.com/(22w4d4zyybpwse1mt3hjni2n)/Home.aspx

Advantage of cookieless session is that they work on clients which don't support cookies or disabled them through browser's settings. Cookieless sessions are considered as less secure than sessions which use cookies because session id embeded in URL is much easier to obtain. They are a lot of possible ways: attacker could use network monitoring tool, maybe get access to web server's log where all requested URLs are listed etc.

In the other hand, visitor could disable cookies due to privacy reasons (and ironically end up with less privacy if session id is stolen), or have browser which doesn't support cookies. If you use sessions with cookies, then visitors like these will not be able to use application. As compromise, ASP.NET offers cookieless="AutoDetect" option. If cookieless parameter is set to AutoDetect, ASP.NET will store sessions in cookies if certain browser supports them, and place session id in URLs if client is not supporting cookies. Notice that visitors without cookies support will be less secure, but it is up to you to decide is it better solution that someone will be less secure or to completely deny access to application for those visitors.

Victim can send link manually through an email, messenger etc. If you use cookieless sessions, inside sessionState element, set regenerateExpiredSessionID parameter to true, to avoid reusing of old sessions that should be expired.

Mark session cookie as secure

Even if you use sessions with cookies, it is possible that attacker will read cookie's value and steal session id. For highly secure web applications, use HTTPS protocol and mark session cookie as secure. This works pretty nice, SSL enabled website will protect not just session cookie, but also application cookie, all request/response information etc. The problem could occur if you secured only part of the website and have public area where you use common HTTP protocol.

Decrease session timeout

By default, ASP.NET session timeout is set to 20 minutes. That means that session will expire if visitor doesn't make any request in 20 minutes interval. Value of session timeout can be changed. In some cases, you can increase session timeout value to avoid session expiration (e.g. if visitor fills some long complex form, survey etc.).

As opposite to these cases, highly secured websites, like banking systems, often have shorter session timeout (e.g. 5 minutes). This short timeout usually causes frequent session expiration which could be very annoying. To get good user experience, you should avoid short session timeouts when ever is possible. But, in case of very sensitive information like working with money, bad user experience is considered as justified. If you used public computer and forgot to log-out from application, short timeout will prevent someone else to continue using your session. Common thinking is that is better to have session expired here and there, than to discover that someone spent all money from your bank account.

Client side redirection when session is expired

ASP.NET session is expired if there are no new requests longer than session timeout. But, ASP.NET doesn't know if visitor actually closed browser or just gone to coffee break and will return soon. Security problem occurs if page contains sensitive data. Even if session is expired, private data will still be displayed on client's screen. In case of public computer in Internet cafe, or even at work if user goes from office to lunch break and forget to log-out from Windows, sensitive data will be visible to anyone close to user's computer.

The possible solution is to redirect visitor using meta refresh to some Your-Session-Is-Expired.aspx page immediately after session is expired. More about checking if session is expired and redirecting if needed you can find in How to find if ASP.NET session is expired tutorial.

Remarks

In this tutorial, I covered some common security practices when working with ASP.NET Session State. Please note that session state cookie and authentication cookie are two different things, independent of each other. Session State is not designed for extra sensitive information. Data stored in sessions should be considered as public, so for critical data avoid using of session state. Instead, use Forms or Windows Authentication which are considered as more secure.

Thus, avoid using of session as temporally password across the website. Condition like If Session("IsLoggedIn") = True Then..., is not recommended from security perspective. Instead, use Forms or Windows authentication to check if user is logged, does he or she has an access to certain site's section and for all other administrative tasks. For example, to see if current user is logged in or is not, simply check value of User.Identity.IsAuthenticated property. To limit access for certain users or roles in complete folder you can also use <authorization> element in local web.config files.

Notice that using of SSL is secure but also decreases performances. If you use SSL, to get faster load take additional efforts to make page size as small as possible. More about how to get smaller page size you can find in How To Reduce Page Size In ASP.NET tutorial.

Happy coding!


Tutorial toolbar:  Tell A Friend  |  Add to favorites  |  Feedback  |   Google


comments powered by Disqus