14

Ruby on Rails has supported signed cookie-based sessions for quite some time, with a few encrypted implementations springing up since then. Python and PHP also have implementations.

Does such a beast exist for the Java servlet containers Jetty or Tomcat?

We've received significant performance gains over RDBMS-based sessions with the PHP implementation in our clustered environment, and I'd be interested in trying something similar with one of our Java applications (which currently uses Jetty 7).

I'm aware of other ways to achieve this goal (memcached, synchronized in-memory caches) but I believe that for our particular needs the limitations of this storage method (sessions finalization before output, in-efficient storage after the 4K cookie size limit, reliance on an ultra-secret server-side key) are outweighed by the simpler deployment environment for this particular application.

If an implementation doesn't exist, does anybody have any ideas why it wouldn't? (e.g. Java sessions are typically larger than 4K, and so aren't as amenable to this storage method)

Amro
  • 123,847
  • 25
  • 243
  • 454
tjdett
  • 1,703
  • 1
  • 18
  • 23

3 Answers3

10

We have implemented the Session-In-Cookie and used it successfully in a Tomcat cluster to allow session-sharing among 20 nodes and thus enable zero-outage deployments. I have just written the first part of a two-part series on the implementation here: http://blog.shinetech.com/2012/12/18/simple-session-sharing-in-tomcat-cluster-using-the-session-in-cookie-pattern/. This part deals with the basic implementation, the security aspects will be covered in the second part.

MarcFasel
  • 1,080
  • 10
  • 19
  • 1
    After almost two years, you've answered my question: 1) it does exist, because you've implemented it, and 2) it hasn't been done until now because of the "committed response" issues with the approach. – tjdett Jan 07 '13 at 04:10
1

It seems like there are two questions here:

  1. Java/J2EE implementations of effectively stateless session-management.
  2. Secure session implementations.

Regarding the first question: Yes, depending on the size of the session-graph (deep nesting of all session variables/objects) the cookie size limitation (which is effectively an HTTP Header limitation) is a significant factor. If the session-graph neatly fits inside the HTTP Header limitation (which is to some extent configurable on the web-server side) and/or can be augmented with REST based URL query parameters (to alleviate some of the state information on the server) ... then a cookie implementation is possible. This would be programmatic versus container-managed however.

Regarding the second question: Securing sessions is another matter. The notorious JSESSIONID common cookie in Java/J2EE systems is a simple token key to the in-memory or disk-cached session on the application server. It is just a map key. With that key, anyone can steal or impersonate the user-session. This is probably one of the weakest links in the entire container-managed session apparatus. There are commercial secure-session products available that prevent session-hijacking by cookie stealing, prevent replay-attacks (that can defeat SSL by capturing the replaying the encrypted login conversation to obtain a session) and other attack vectors. One product I am aware of can do this with no changes to the code (via a security filter). However, I am not aware of any general frameworks or open-source initiatives to plug this hole, probably because it requires a level of expertise that is beyond general application development.

Darrell Teague
  • 4,132
  • 1
  • 26
  • 38
1

I'm not aware of anything in either container that would serialize a HttpSession to a cookie for you. You could achieve this sort of thing by implementing a Filter that would be able to serialize session state to a cookie on a response to a web client and deserialize it on the request. You are still bound to any client side cookie limitations and you should carefully consider the security implications of the state you are storing client side and/or how much you trust the client presenting the cookie.

philwb
  • 3,805
  • 19
  • 20
  • The serialization problem would appear to be an issue which [JDBCSessionManager](http://docs.codehaus.org/display/JETTY/Session+Clustering+with+a+Database) and [jetty-session-memcached](http://code.google.com/p/jetty-session-memcached/) already deal with. The application I'm planning to trial already uses the former implementation, and the only issues I've had relate to ensuring any classes storing the session exist in the container, not servlet, context. – tjdett Apr 19 '11 at 06:46
  • As for security implications, can you think of any beyond: * Ensure the implementation stores the session expiry date inside the encrypted cookie and enforces it on the server-side, to prevent perpetually reuse of hijacked cookies. * Avoid using this implementation for any application where the ability to "undo" session changes would pose a risk. * Keep the encryption key VERY safe! I'd like to know if I'm missing anything. – tjdett Apr 19 '11 at 07:00
  • I think you may be confusing 2 ideas - session clustering in jetty is about sharing session state between 2 or more server instances; yes you would need to be concerned with the serialization of the objects attached to the HttpSession. In this case, the jsessionid, typically cookie based, is an identifier used by any of the server instances to locate the shared session. Hence you can load balance between the servers in a variety of ways. However, this is not the same as serializing the relevant session state to a cookie. In that case, you don't need session clustering at the server. More.. – philwb Apr 19 '11 at 15:55
  • ...For the case of cookie storage, you just need to represent the relevant state in the cookie and, in the example in the answer, your filter would then take care of inflating/deflating the relevant HttpSession attributes. As for security, you should start with a basic threat assessment to decide what to worry about protecting, but, in general, cookie state is not beyond any type of tampering. If you store sensitive information (passwords, private info, etc.) then it could be retrieved by an attacker. You also have to judge how trustworthy are your clients - if you rely on information... – philwb Apr 19 '11 at 15:59
  • ...about the client to be sent to you by the client, you need to have some trust that the client isn't sending you bogus information or trying to gain authorizations that the client wouldn't normally have. So, let your threat assessment guide you but do be aware of the consequences. – philwb Apr 19 '11 at 16:01
  • @philwb Yes, any cookie-based implementation would have to implement session serialization - my point was simply that there are already two other session-storage implementations which implement serialization, so it's not an insurmountable problem. JDBCSessionManager uses an [ObjectInputStream](http://download.oracle.com/javase/6/docs/api/java/io/ObjectInputStream.html)/[ObjectOutputStream](http://download.oracle.com/javase/6/docs/api/java/io/ObjectOutputStream.html). Presumably if I'm writing my own implementation, I'll be studying that. (more...) – tjdett Apr 19 '11 at 23:13
  • @philwb As for client trust: have you read any of the links related to the Ruby/Python/PHP implementations? All of those implementations either encrypt or sign the session store cookie, which means that modification of the cookie data would require you to know the server-side secret/key. Substitution of a previous cookie is certainly possible under some circumstances, but creation and/or modification of new session data is **not** provided the server-side key remains secret. As you point out, a signing-implementation would not be viable if storing sensitive data - I'd use encryption instead. – tjdett Apr 19 '11 at 23:30
  • I'm still not sure you've got these two ideas separated. In a servlet container, like Jetty, the session is an HttpSession. Serialization of that object, which would serialize all of the attached state objects, would be used to cluster it across servers. You would not serialize an entire HttpSession to a cookie. You would only serialize the state that your application is interested in. And, you would probably not want to use java object serialization to do it but something more compact. As for the security, yes, I understand the need to encrypt the data. However, your reliance on ... – philwb Apr 20 '11 at 02:41
  • ...encryption should include a basic threat assessment. For instance, if you are just holding the user's first name, there is probably no real threat to someone breaking the encryption. If you are holding something like a credit card number (just to have an outrageous example) then it is highly likely that someone will invest some effort into breaking your encryption. Again, you need to assess the threats that you face and react accordingly. If your information is just simple state or not terrible if it is compromised, then it will probably be ok to keep it on the cookie. Else...take care – philwb Apr 20 '11 at 02:44
  • One final note - if you do decide to store the state in a cookie, you probably don't need to be concerned with session clustering at the server as you can reconstitute the session on each call. Whether or not you need some additional cache technologies to make that performant will depend on your own situation. Good luck and happy coding! – philwb Apr 20 '11 at 02:46