Thursday, February 23, 2017

Session Session-fixation And the Fix

        

Session -
In general a web session or http session or user session is a conversational state between client(browser) and server and it can consists of multiple request and response between client and server.
From a developer’s viewpoint a session can be defined as a server-side storage of information in key-value pair that is desired to persist throughout the user's interaction with the web site or web application. For example we need to store user authentication details on successful login, so that next time the user requests a page we can provide him the page without asking him to login, as from the session we can check if the user is already authenticated. Sessions are usually created and maintained by the container like Tomcat, GlassFish etc.

Session Id -
As HTTP is stateless i.e each request is an independent transaction and unrelated to any previous request. There needs a way to identify which session belongs to which user, so that we can store and retrieve user related information in that particular session. This can be achieved by a Session Id cookie. When a session is first created the container binds that session with a unique Session Id and stores that id as a cookie in user's browser. Next time user makes a request the session id cookie comes along with the request and from that session id the server determines the particular session for a user.

Now if the session id falls to a malicious hand then he can hijack the session and do transactions on behalf of the authentic user. All he needs to do is modify his session id cookie value with authenticated user’s session id cookie value.

From Java perspective-
Java servlet API provides ways to create a new session or get the existing one. When the session is first created the container, let’s say Tomcat will store a cookie JSESSIONID in user’s browser. You can check that cookie with firebug or chrome developer tool. If using framework like spring then the session is created by the framework and developer do not need to do that manually.

From now on the issue will be described from Java view point and the solution as well for java.

Session Fixation Attack-
Session fixation attack is a kind of session hijacking where the victim is targeted before login. The attack explores a limitation in the way the web application manages the session and session ID, when authenticating a user. It doesn’t create a new session or assign a new session ID after authentication, rather uses the session and session ID that it created before authentication. Making it possible for the attacker to fixate the user session. Following step by step illustration of the concept can make it more clear.

Step 1 - Attacker visits a site, say a bank site developed in java. Now he has a JSESSIONID cookie in his browser.
Step 2 - Attacker uses social engineering and persuades an authentic user(victim) to login with that JSESSIONID.
Step 3 - Now after receiving the credentials, server authenticates the victim and attaches the session that was initially created by the Attacker, as it gets the associated JSESSIONID from victim’s browser, and maps it to the already existing session.
Step 4 - As the attacker has the session identifier i.e. JSESSIONID with him and the server has not changed the JSESSIONID after login, the Attacker can access the authenticated session providing the JSESSIONID, and do transactions on behalf of user, till the session exists i.e. the victim is not logging out.

Ways to mitigate the session hijacking attack -
# Making the JSESSIONID secure and cookie only. This will prevent Attacker from sending the JSESSIONID in url i.e URL rewriting. To achieve this we need to add following lines in web.xml available since servlet 3.0
<session-config>
         <!--Securing the cookies-->
          <cookie-config>
              <!--prevent an XSS (Cross-Site Scripting) exploit-->
              <http-only>true</http-only>
              <secure>true</secure>
          </cookie-config>
          <!--Disable session rewrite in the URL-->
          <tracking-mode>COOKIE</tracking-mode>
      </session-config>

When using java config
      servletContext.setSessionTrackingModes(EnumSet.of(SessionTrackingMode.COOKIE));
     
Ways specific to session-fixation-
# Create new session or migrate existing session after successful login. Do not create session until the user is authenticated or once the user is authenticated create another session for that user or migrate the existing session.
If working directly with Servlet or JSP the first choice i.e create session only after user login is pretty simple. Call the HttpServletRequest's getSession() method only after the login is done. If session creation is needed prior to login, then after login migrate the session by creating a new session and copying the data from earlier session.

Spring security support for session-fixation
When working with Spring mvc and spring security, developer's hold on session creation is limited. However spring security provides excellent support to mitigate the session-fixation issue. From spring security 3.0 it has a default implementation to deal with the session-fixation issue, where it migrates the session after user authentication. If you are not happy with the implementation you can change it as per the need. Changes will be as shown below and will go into the security config file or its java config equivalent.   
     
<http>
                 <session-management session-fixation-protection="newSession">
           </http>
   Java config equivalent
      http.sessionManagement().sessionFixation().newSession()
     
# With all this we still have the open issue of same JSESSIONID. Though the spring security newSession functionality creates a new session still the JSESSIONID is same as before authentication and the main focus of this blog is to address that issue. The solution is small changes in config files and it goes in your security context authentication filter like this...

   <beans:bean id="myAuthFilter" class=
"org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter">
   <!--bean to change jsession id after login-->
       <beans:property name="sessionAuthenticationStrategy">
           <beans:bean class="org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy"/>
       </beans:property>
   ...
</beans:bean>

Using Java config for spring security then it is already implemented in a elegant way and all you need to do is make your security config class to extend WebSecurityConfigurerAdapter.

Well that is it, happy reading.