Thursday, December 23, 2010

How to secure Classic ASP Session ID with JAVASCRIPT

     To secure our websites, we need to secure our session ID. Although there are solutions for Asp.net and other programming languages, there isn't any solution for classic asp. 
     There is not any built-in features in classic asp to achieve that. So I have to invent my own way to secure it based on the available language's features and by adding some tweaks.
     First of all, to secure the asp session ID, we need to change session ID after authentication and set two flags to asp session cookie, httponly and secure flags. Unfortunately, classic asp's session ID is read-only and we cannot set it directly from vbscript. And asp session ID is generated randomly, we need some tweaks to get both key and the value. Here are the steps:
  1. Read current asp session id's key at login page.
  2. When user login request is sent to authentication page, send this session key.
  3. If the user is authorized, set invalid value to current session id and that will force the web server to generate new session id. 
  4. Redirect the page to new page to get a new session id.
  5. Read new session id's key and value
  6. Send new session id to new page
  7. Add httponly and secure flag to new session id.

Step 1: Login page (login.asp).
<html>
<head>
<script type="text/javascript">
        function getSessionKey()
        {
        var c_name = "ASPSESSIONID";
        if (document.cookie.length>0)
          {
          c_start=document.cookie.indexOf(c_name);
          if (c_start!=-1)
            {
            c_end=document.cookie.indexOf("=",c_start);
            if (c_end==-1) c_end=document.cookie.length;
            return unescape(document.cookie.substring(c_start,c_end));
            }
          }
        return "";
        }
        
        function submit()
        {
            document.login.sessionid.value = getSessionKey();
        }
</script>
</head>
<body onload="submit()">
<form name="login" onsubmit="" action="authenticate.asp">
<input type="text" name="username" />
<input type="text" name="password" />
<input type="hidden" name="sessionid" value="" />
<input type="submit" value="Login" />
</form>
</body>
</html>
Here current session id will be read and will store it in the hidden field. When the form is submitted, this hidden value will also be sent.

Step 2: Authentication page (authenticate.asp).

<%
    'CODE for authorization/authentication
    '...
    
    'if login successful
    'delete the current session id to generate new one
    Response.AddHeader "Set-Cookie", Request("SessionID") & "=0"
    'redirect to another page to get new session id
    Response.Redirect "NewSession.asp"
%>

Here current session id will be read from the request's form field. Set invalid value to it and redirect to another page. When setting invalid value to Session ID, the web server will re-generate new session ID and will send it to the browser in subsequent response.

Step 3: Reading new session key (NewSession.asp)
<html>
<head>
<script type="text/javascript">
        
        function getCookie()
        {
         var c_name = "ASPSESSIONID";
         var cok;
        if (document.cookie.length>0)
          {
          c_start=document.cookie.indexOf(c_name);
          if (c_start!=-1)
            {
            //c_start=c_start + c_name.length+1;
            c_end=document.cookie.indexOf(";",c_start);
            if (c_end==-1)
            { 
                c_end=document.cookie.length;
                cok = unescape(document.cookie.substring(c_start,c_end) + ';');
            }
            else
            {
                cok = unescape(document.cookie.substring(c_start,c_end));
            }
            return cok;
            }
          }
        return "";
        }
        
        function submit()
        {
            document.login.sessionid.value = getCookie();
            document.login.submit();
        }
</script>
</head>
<body onload="submit()">
<form name="login" onsubmit="" action="UserAccount.asp">
<input type="hidden" name="sessionid" value="" />
</form>
</body>
</html>
Here new session id will be read from cookie and assign it to the hidden field. When the form is submitted, this hidden value will also be sent. In the next page, this new session ID will be retrieved and set two flags.


Step 4: Privileged page (UserAccount.asp).
<%
    Response.AddHeader "Set-Cookie", Request("SessionID") & "secure;httponly"
%>

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <script type="text/javascript">        
        alert(document.cookie);
    </script>
</head>
<body onload="">
    ASP Session ID has been secured. :)
    <a href="session5.asp">visit</a>
</body>
</html>
Here current session id will be read from the request and append "secure" and "httponly" flags to them. By adding these two flags, session ID will only be sent to the client when using secure channel and session ID will no longer be accessible from client side javascript. This will prevent XSS (cross site scripting).

We are done!

:)

11 comments:

  1. Great blog! and thanks so much for the info!...

    Question, have you done any fb integration using classic asp? I am stuck on a JSON piece of code.. perhaps you can drop me a quick note..

    thanks in advance.

    ReplyDelete
  2. can you show me sample lines of code and your problem?

    ReplyDelete
  3. the easiest way to change the sessionid wouldn't be to simply put a session.abandon command line AT THE END of the authentication page ?
    Actually the worst issue isn't to change the sessionid, it's that iis generates it sequencially...
    I didNt, try your code, but, reading it, for me means that your goal is mainly changing the sessionid, and of course put a secure and httponly to it.....am i wrong ?

    ReplyDelete
  4. This code is not working in classic ASP any more

    ReplyDelete
  5. I found your blog while searching for the updates, I am happy to be here. Very useful content and also easily understandable providing..
    Believe me I did wrote an post about tutorials for beginners with reference of your blog. 




    Selenium training in bangalore
    Selenium training in Chennai
    Selenium training in Bangalore
    Selenium training in Pune
    Selenium Online training

    ReplyDelete
  6. This comment has been removed by the author.

    ReplyDelete
  7. Great post! It’s very helpful for this blog. Also great with all of the valuable information you have Keep up the good work you are doing well.

    AWS training in Chennai

    AWS Online Training in Chennai

    AWS training in Bangalore

    AWS training in Hyderabad

    AWS training in Coimbatore

    AWS training

    ReplyDelete
  8. This comment has been removed by the author.

    ReplyDelete