Skip to content

SEC-2135: Support Servlet 3.1's HttpServletRequest#changeSessionId() as alternate session fixation protection strategy #2361

Closed
@spring-projects-issues

Description

@spring-projects-issues

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," use SessionFixationProtectionStrategy with migrateSessionAttributes set to false.
  • If session-fixation-protection is "migrateSession," use SessionFixationProtectionStrategy with migrateSessionAttributes set to true.
  • An old @Deprecated List<String> retainedAttributes property on SessionFixationProtectionStrategy that allows specifying a list of attributes that will be retained if migrateSessionAttributes is set to false.

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?

Metadata

Metadata

Assignees

Labels

in: webAn issue in web modules (web, webmvc)type: enhancementA general enhancementtype: jiraAn issue that was migrated from JIRA

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions