Saturday, March 31, 2012

Hunting asp.net Authentication and Session Ghosts

Asp.net handles the features of user authentication and user session in two different ways that sometimes may produce ghosts (bugs difficult to find) in our web applications.

The default forms authentication time is 20 mins. Session timeout is extended (to another 20 mins) for every request made to the server.
The default session time is 30 mins. When sliding expiration is true (that is the default), authentication timeout is extended for every request made to the server only after the first half of the total authentication time. The extension time is another 30 mins.
The above, is implemented in web.config as follows:
    <authentication mode="Forms">
      <forms domain="" name="AuthCookie" />
    </authentication>
    <sessionState mode="InProc" cookieless="false" />

Consider the following schema:
Session        [....................] 20' (default timeout)
                <----- 20mins ----->        

                Sliding Expiration = TRUE, Works only for requests after the 2nd half
                              /
                             15'
Authentication [..............|...............] 30' (default timeout)
                <----------- 30mins --------->

               
The time proportion between Authentication duration and Session duration is 30/20 = 1.5 which is the default value adopted by Microsoft.
               
Let assume the following:
1. Suppose that we have created a web application on asp.net X where X in (2, 3, 3.5 or 4).
2. We are also supposing that this application is using the default membership provider provided by Microsoft.
3. Our login form requires username, password and the user's full name. I use session to store the last one since username and password are part of the default membership and they are handled via System.Security.Principal.IIdentity, but full name not. Someone could suggest to extent the above membership in order to handle the user's full name (or other related fields) but this will break the scope of this article which is to show some traps of the usage of session variables.

Thus, the user's full name is stored on a session variable immediately after a successful login as follows:
...
Session("UserFullname") = txtFullname.text
...

Suppose that a the user login to our application at 12:00am. After his login the user waits for a number of minutes before send make a new action, i.e. send a new request to the web server. Our program may have different baehaviour depending of this number of minutes. Consider the following cases:

Case I: User sends his last request at 12:16 (16 minutes after authentication )
In this case the session duration will remain lower than the authentication duration (initial state).

                            User
                         request         
             12:00         12:16                               timeout
Authentication [..............|^.............................] 12:46
                               <------------ 30mins -------->

                                                     timeout
Session        [..............[....................] 12:36

                               <----- 20mins ----->
Supposing that the user always send a request to the server at the second half of the authentication duration then we can always be sure that our session variable 'UserFullname' will have the correct value.
                              

Case II: User sends a request at 12:14 (14 minutes after authentication)
In this case the session duration will be greater than the authentication duration.

                          User
                       request
              12:00      12:14                timeout
Authentication [.............^|...............] 12:30
                <------------ 30mins -------->
                                                        timeout
Session        [........................................] 12:40 (refreshed)
                <----- 20mins -----><----- 20mins ----->

This means this: From 12:30 to 12:40 our session variable 'UserFullname' will be invalid (empty).

The time proportion between Authentication duration and Session duration is 30/40 = 0.75.

According to the above we can conclude that:
If the proportion of authentication and session duration is lower than zero and Sliding Expiration is set to 'true' then there is a high possibility to "loose" our session variables or it is not safe to base the logic of our web application in session variables.

9 comments:

  1. I think Session is almost never a good idea to store information.
    All items that are stored in Session can be removed if IIS recycles the application pool in which our web application runs.

    ReplyDelete
  2. Geia soy Taso!
    Thanks for your comment. I must say that I partially agree with you. :)
    Session is removed by recycling pool only if sessionState mode="InProc".
    In case that sessionState mode="StateServer"; session var/s are not cleared given that ASP.NET service is already running.

    ReplyDelete
  3. Kalimera Andrea!
    You are right about sessionState mode="StateServer". But in cases of shared hosting, I have the impression that this option is not always available, and thus we are left only with the InProc option.

    Also, there is the SQLServer option where one could store all its Session data to an Sql Server.

    ReplyDelete
    Replies
    1. @ Tasos, both true.
      On the other hand, you just scratch a very interesting (fmo) topic.
      Share Hosting or VPS?
      In case that we are talking about a web development company, a small team or even a freelancer my favorite proposition is using a VPS (or even a DEDI server). In such environments you have the complete control over IIS / ASP.Net or other Libs/DLLs that may require system access level to be installed.
      Nowdays (fmo again!) share hosting is appropriate to non-programmers such as advanced user etc, in order to setup and maintain ready-made packages as WP, PhpBB, Website Creator, etc etc... ;)

      Delete
    2. Your answer kinda surprised me. My main concern in a such scenario is security.

      I work in a web development company and we rely on shared hosting solutions to host our websites. We use our own CMS which is developed in ASP.NET.

      If we switch to a dedicated web server or a virtual cloud server, how can we be protected from attacks? Both server wide or specific to a domain?



      Delete
    3. Off Topic Begin

      If your main concern is security then you have to avoid share hosting for sure!
      Most of the sites on share hosting env/s get p0wned because of some bad configurion of one site that allows an attacker to get a shell on it and then get root then... having all!
      Share hosting follow the rule "A chain is only as strong as its weakest link"!
      You HAVE to know how to protect your box.
      There are plenty of tools out there. The only "problem" is the learning curve. Ok, as developer you don't have to know this but fmo YOU SHOULD!
      In addition there are plenty SLAs out there that allows you to have even a DEDI server using all the benefits of a hardware IDS provided by your provider.
      We are talking about Protection at the lowest network level... and not only :-)

      Off Topic End

      Delete
    4. Andreas, sorry for going off topic in my previous comment, and thanks anyway for your answer! :-)

      Delete
    5. No problem Tasos.
      The only problem is that this is a blog and the environment itself does not give us the opportunity for such arguments.
      I strongly suggest you to join our forum @ http://www.p0wnbox.com where we can enjoy and discuss any related topic you/we like!
      ;-)

      Thank you!

      Delete

Note: Only a member of this blog may post a comment.