An http session impersonation protection filter

Session Impersonation is an attack which works for webapps and dynamic websites. Someone steals your session cookie (possibly by using XSS – Cross Site Scripting), injects it into his browser visits the site and suddenly appears to be you. If you happened to be logged in as the single superadmin of the system, then he is a superadmin as well.

One of the ways to avoid this problem is by storing a hash (or token) the first time the http session is created. That hash will contain the user’s IP address and his user agent (the browser he uses). On each following request, the hash is being recalculated, and must match the hash previously stored in the http session. If it does not match, any of the 3 things might have happened:

  1. Client has changed his IP.
  2. Client has changed his user agent String.
  3. Client is using another clients session (session impersonation attack).

Changing you IP is hard (unless your ISP is AOL or you use an anonymity service such as TOR). Changing browsers will initiate a new http session anyway, and changing your user-agent String is rare. It can be done in Firefox using the about:config page but that’s not a thing that users do everyday.

Note that session impersonation protection is hard (impossible?) to do when people use the same IP. That can be the case in universities, companies and netcafes.

Here is the doFilter method of an http filter which you can use to protect your application from session impersonation attacks. It will invalidate the session when this happens.

if (request instanceof HttpServletRequest) {
  HttpServletRequest httpRequest = (HttpServletRequest)request;
  // get the session, without creating one if there isn't any
  HttpSession session = httpRequest.getSession(false);
  // if there is a session
  if (session!=null) {
    //calculate a hash using ip and user agent
    String hash = getHash(httpRequest.getRemoteAddr(),
        httpRequest.getHeader(USER_AGENT_KEY));
    if (session.getAttribute(HASH_KEY)==null) {
      // put hash in session
      session.setAttribute(HASH_KEY, hash);
    } else {
      // session does not contain hash
      if(!hash.equals(session.getAttribute(HASH_KEY))) {
        // TODO log session impersonation attempt?
        session.invalidate();
      }
    }
  }
}
chain.doFilter(request, response);

The getHash method could just return the two Strings concatenated, but ideally you should hash them.

public static final String getHash(String ip, String agent) {
  return Integer.toString(ip.hashCode()) + agent.hashCode();
}

MD5 would be good but usually it’s costly. Here I just used String#hashCode.
You’ll also need two constants for the filter:

public static final String HASH_KEY = "HASH";
public static final String USER_AGENT_KEY = "user-agent";

Thats it. Set the filter on the top of your filters chain and you are ready.

One Response to “An http session impersonation protection filter”

  1. PHP Sessions + Useragent with salt - PHP Solutions - Developers Q & A Says:

    [...] do that as well to partially protect from session impersonation attacks. You need to include the IP address as [...]