Description
Nick Williams (Migrated from SEC-2135) said:
The Servlet 3.1 specification, set to release in the next month or two, adds a new method to HttpServletRequest
that supports changing the ID of a session as an approach to session fixation protection. This is a more ideal approach than Spring Security's current approach of creating a new session, copying all (or part) of the contents of the current session to the new session, then invalidating the old session. Using the changeSessionId
method over Spring Security's current strategies would likely achieve a performance improvement, especially in a high-load scenario.
As a developer using Spring Security, I need SS to support calling changeSessionId
as alternate session fixation protection strategy. I would be glad to implement this and submit the pull request, but it's a big change so I'd like to have a discussion and get some buy-in on my planned design before I set to work.
First: Timeline Considerations
I don't know what the product roadmap is for Spring Security, but based on previous release cycles, I'm guessing you're targeting 3.2.0.M2 by March 1, M3 by April 1 and GA by May 3, putting it about 5 months behind Spring 3.2.0.GA (not saying that's a bad thing, just laying out some observations). If that timeline holds true, I'm guessing we can expect Spring Security 4.0 about this time next year and maybe a little later. I'd love to see support for changeSessionId
before then.
Second: Technical Considerations
My belief in how this would technically work is that a new option would be added to the session-fixation-protection
namespace attribute (currently "none," "newSession," and "migrateSession"). For argument's sake, let's call this new option "changeSessionId." I believe if the documentation clearly stated that this option required Servlet 3.1, we could implement it in SS 3.x. If the "changeSessionId" option was specified in an older Servlet environment, a configuration exception would be thrown. Then we could use reflection to access changeSessionId
so that we didn't have to compile against Servlet 3.1.
Third: Design Considerations
I think the largest roadblock to implementing this in SS 3.x is the idea of design. Looking through the code and sketching some things out, I'm having a hard time imagining changing it without subtracting from the public interface of SessionFixationProtectionStrategy
. Current algorithm:
- If
session-fixation-protection
is "none," a different class is used (not a problem). - If
session-fixation-protection
is "newSession," useSessionFixationProtectionStrategy
withmigrateSessionAttributes
set tofalse
. - If
session-fixation-protection
is "migrateSession," useSessionFixationProtectionStrategy
withmigrateSessionAttributes
set totrue
. - An old
@Deprecated List<String> retainedAttributes
property onSessionFixationProtectionStrategy
that allows specifying a list of attributes that will be retained ifmigrateSessionAttributes
is set tofalse
.
The problem is migrateSessionAttributes
and retainedAttributes
. The code that decides between these is already a little confusing. If we were to add the "changeSessionId" option to session-fixation-protection
, we would now have to have a third property and do a mutual exclusion among them all (if we wanted to avoid subtracting from the public interface). The logic becomes sketchy and confusing and would make configuration more difficult.
The simpler alternative would be to remove the migrateSessionAttributes
and retainedAttributes
completely and replace them with an Enum and a single property for that Enum. The Enum's options would be NEW_SESSION, MIGRATE_SESSION and CHANGE_SESSION_ID and those would map to "newSession," "migrateSession" and "changeSessionId," respectively.
The second option is "the right way," IMO, but that is ignoring the fact that this is an existing software that people are using. The first option is more friendly because it doesn't break backwards compatibility. However, the impact of the second option could be lessened by the fact that most people use the session-fixation-protection
namespace attribute to configure this and don't bother with the SessionFixationProtectionStrategy
class directly. How many people actually use SessionFixationProtectionStrategy
directly? That's a question I don't have the answer to.
An alternative third option would be to pick a suitable default (perhaps "migrateSession," which is currently the default anyway) and deprecate migrateSessionAttributes
as well, then change the documentation for migrateSessionAttributes
and retainedAttributes
to say that they are now ignored and the default will be chosen if you don't use the Enum. This has the advantage of not breaking consuming projects' builds, but likewise has the disadvantage of masking when someone is using a method that isn't supported anymore (assuming they ignore compile warnings).
I know that SpringSource occasionally changes interfaces between ?.x releases (I had compile errors when upgrading from Spring Framework 3.0 to 3.1). So the question is, how big of a deal is it if the interface of this class changes in 3.2? We could always wait for 4.0, but like I said, I reaaaalllly don't want to wait that long. :-)
Thoughts?