Experiment with Session Fixation using Tomcat

Session Fixation is a security vulnerability in web sites. The scenario is this:

  • The attacker creates a link to SomeOnlineBank.com in which the URL contains a session ID.
  • The user follows the link and the web site platform uses the session ID.
  • The user logs on, making that session authenticated.
  • The attacker uses the session ID to impersonate the user and steal all of their money.

I was able to reproduce the attack, and mitigate it by changing settings in web.xml. If you use the standard

@WebServlet("/SessionTestServlet")
public class SessionTestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		response.setContentType("text/plain");
		PrintWriter writer = response.getWriter();
		writer.println("Requested Session Id: " + request.getRequestedSessionId());
		writer.println("Session Id valid: " + request.isRequestedSessionIdValid());
		writer.println("Session from parameter: " + request.isRequestedSessionIdFromURL());
		writer.println("Session from cookie: " + request.isRequestedSessionIdFromCookie());

		HttpSession session = request.getSession();
		writer.println("Actual session ID: " + session.getId());
		writer.println("Session is new: " + session.isNew());
	}
}

If I run this servlet and try to inject a Session ID I see the following (requesting http://localhost:8080/TestApp/SessionTestServlet;jsessionid=1234567)

Requested Session Id: 1234567
Session Id valid: false
Session from parameter: true
Session from cookie: false
Actual session ID: 4D041A13FEBC9CD90523BAAB2B5C1B08
Session is new: true

The resulting session is placed into a cookie, and reused for subsequent attempts.

If I change browser and try the URL http://localhost:8080/TestApp/SessionTestServlet;jsessionid=4D041A13FEBC9CD90523BAAB2B5C1B08
I see

Requested Session Id: 4D041A13FEBC9CD90523BAAB2B5C1B08
Session Id valid: true
Session from parameter: true
Session from cookie: false
Actual session ID: 4D041A13FEBC9CD90523BAAB2B5C1B08
Session is new: false

Two browsers are sharing the same Session. I have successfully fixated the session – at least until something happens to change it.

The attack seems limited in a way. I have to make sure my source session is still alive when my victim clicks on the link. This can be done using simple javascript. The same javascript running on my machine could inform me that the victim has logged on and automate the next stage of the attack.

The response from the above request did not set a cookie. If the web site does not allow the servlet container to perform URL rewriting then the stolen Session may be lost.

Mitigation

Try turning off URL Rewriting

Setting the tracking mode to COOKIE only in web.xml seems sufficient. Now it ignores any attempt to pass jsessionid through the matrix parameter. I’ve also set the cookie to “HTTP Only” to prevent access from malicious scripts. I could set “Secure” if I was using HTTPS and did not want my session to be access from a non-HTTPS page. Setting “Secure” prevents sessions being created on non-HTTPS pages.

	<session-config>
		<tracking-mode>COOKIE</tracking-mode>
		<cookie-config>
			<http-only>true</http-only>
		</cookie-config>
	</session-config>

Verify the client IP address

It is possible to track the client IP address and verify it for future requests. This is not foolproof. For example Network Address Translation or a shared internet proxy would fool it.

Invalidate the Session on logon

Tomcat7 will automatically change the Session ID when Container Security is used to logon. The application I work with implements its own logon management, so has to take its own precautions. It also uses Java CDI so this may be a little harder.

If I invalidate and recreate the Session then I notice that the ID changes every time.

HttpSession session = request.getSession();
session.invalidate();
session = request.getSession();

I’ve not tested this in a CDI environment.

This entry was posted in java. Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *