Talk about sessionfixations



This article mainly talks about the prevention of session fixation attacks and spring security.

session fixation attacks

Session fixed attack is to obtain login status by exploiting loopholes that have no change in sessionId before and after login, and then obtain relevant information of users, etc.

Servlet3.1 specification

In the servlet3.1 specification, explicitly specifies a method to changeSessionId
tomcat-embed-core-8.5.23-sources.jar! /javax/servlet/http/

     * Changes the session ID of the session associated with this request. This
     * method does not create a new session object it only changes the ID of the
     * current session.
     * @return the new session ID allocated to the session
     * @see HttpSessionIdListener
     * @since Servlet 3.1
    public String changeSessionId();


spring-security-web-4.2.3.RELEASE-sources.jar! /org/springframework/security/web/authentication/session/

 * Allows pluggable support for HttpSession-related behaviour when an authentication
 * occurs.
 * <p>
 * Typical use would be to make sure a session exists or to change the session Id to guard
 * against session-fixation attacks.
 * @author Luke Taylor
 * @since
public interface SessionAuthenticationStrategy {

     * Performs Http session-related functionality when a new authentication occurs.
     * @throws SessionAuthenticationException if it is decided that the authentication is
     * not allowed for the session. This will typically be because the user has too many
     * sessions open at once.
    void onAuthentication(Authentication authentication, HttpServletRequest request,
            HttpServletResponse response) throws SessionAuthenticationException;


Spring security provides the SessionAuthenticationStrategy interface for handling session-related logic after successful login. It has an abstract class AbstractSessionFixationProtectionStrategy


spring-security-web-4.2.3.RELEASE-sources.jar! /org/springframework/security/web/authentication/session/

     * Called when a user is newly authenticated.
     * <p>
     * If a session already exists, and matches the session Id from the client, a new
     * session will be created, and the session attributes copied to it (if
     * {@code migrateSessionAttributes} is set). If the client's requested session Id is
     * invalid, nothing will be done, since there is no need to change the session Id if
     * it doesn't match the current session.
     * <p>
     * If there is no session, no action is taken unless the {@code alwaysCreateSession}
     * property is set, in which case a session will be created if one doesn't already
     * exist.
    public void onAuthentication(Authentication authentication,
            HttpServletRequest request, HttpServletResponse response) {
        boolean hadSessionAlready = request.getSession(false) != null;

        if (!hadSessionAlready && !alwaysCreateSession) {
            // Session fixation isn't a problem if there's no session


        // Create new session if necessary
        HttpSession session = request.getSession();

        if (hadSessionAlready && request.isRequestedSessionIdValid()) {

            String originalSessionId;
            String newSessionId;
            Object mutex = WebUtils.getSessionMutex(session);
            synchronized (mutex) {
                // We need to migrate to a new session
                originalSessionId = session.getId();

                session = applySessionFixation(request);
                newSessionId = session.getId();

            if (originalSessionId.equals(newSessionId)) {
                logger.warn("Your servlet container did not change the session ID when a new session was created. You will"
                        + " not be adequately protected against session-fixation attacks");

            onSessionChange(originalSessionId, session, authentication);

If servlet3.1 is used, spring security’s default SessionAuthenticationStrategy is ChangeSessionAuthenticationStrategy.


spring-security-config-4.2.3.RELEASE-sources.jar! /org/springframework/security/config/annotation/web/configurers/

     * Creates the default {@link SessionAuthenticationStrategy} for session fixation
     * @return the default {@link SessionAuthenticationStrategy} for session fixation
    private static SessionAuthenticationStrategy createDefaultSessionFixationProtectionStrategy() {
        try {
            return new ChangeSessionIdAuthenticationStrategy();
        catch (IllegalStateException e) {
            return new SessionFixationProtectionStrategy();


spring-security-web-4.2.3.RELEASE-sources.jar! /org/springframework/security/web/authentication/session/

 * Uses {@code HttpServletRequest.changeSessionId()} to protect against session fixation
 * attacks. This is the default implementation for Servlet 3.1+.
 * @author Rob Winch
 * @since 3.2
public final class ChangeSessionIdAuthenticationStrategy
        extends AbstractSessionFixationProtectionStrategy {
    private final Method changeSessionIdMethod;

    public ChangeSessionIdAuthenticationStrategy() {
        Method changeSessionIdMethod = ReflectionUtils
                .findMethod(HttpServletRequest.class, "changeSessionId");
        if (changeSessionIdMethod == null) {
            throw new IllegalStateException(
                    "HttpServletRequest.changeSessionId is undefined. Are you using a Servlet 3.1+ environment?");
        this.changeSessionIdMethod = changeSessionIdMethod;

     * (non-Javadoc)
     * @see
     * AbstractSessionFixationProtectionStrategy
     * #applySessionFixation(javax.servlet.http.HttpServletRequest)
    HttpSession applySessionFixation(HttpServletRequest request) {
        ReflectionUtils.invokeMethod(this.changeSessionIdMethod, request);
        return request.getSession();

Call the changeSessionId method through reflection, specifically call Request#changeSessionId.


tomcat-embed-core-8.5.23-sources.jar! /org/apache/catalina/connector/

     * Changes the session ID of the session associated with this request.
     * @return the old session ID before it was changed
     * @see javax.servlet.http.HttpSessionIdListener
     * @since Servlet 3.1
    public String changeSessionId() {

        Session session = this.getSessionInternal(false);
        if (session == null) {
            throw new IllegalStateException(

        Manager manager = this.getContext().getManager();

        String newSessionId = session.getId();

        return newSessionId;

Changesession id (session) is called here.


tomcat-embed-core-8.5.23-sources.jar! /org/apache/catalina/session/

    public void changeSessionId(Session session) {
        String newId = generateSessionId();
        changeSessionId(session, newId, true, true);
    protected void changeSessionId(Session session, String newId,
            boolean notifySessionListeners, boolean notifyContainerListeners) {
        String oldId = session.getIdInternal();
        session.setId(newId, false);
        session.tellChangedSessionId(newId, oldId,
                notifySessionListeners, notifyContainerListeners);

     * Generate and return a new session identifier.
     * @return a new session id
    protected String generateSessionId() {

        String result = null;

        do {
            if (result != null) {
                // Not thread-safe but if one of multiple increments is lost
                // that is not a big deal since the fact that there was any
                // duplicate is a much bigger issue.

            result = sessionIdGenerator.generateSessionId();

        } while (sessions.containsKey(result));

        return result;


tomcat-embed-core-8.5.23-sources.jar! /org/apache/catalina/util/

public class StandardSessionIdGenerator extends SessionIdGeneratorBase {

    public String generateSessionId(String route) {

        byte random[] = new byte[16];
        int sessionIdLength = getSessionIdLength();

        // Render the result as a String of hexadecimal digits
        // Start with enough space for sessionIdLength and medium route size
        StringBuilder buffer = new StringBuilder(2 * sessionIdLength + 20);

        int resultLenBytes = 0;

        while (resultLenBytes < sessionIdLength) {
            for (int j = 0;
            j < random.length && resultLenBytes < sessionIdLength;
            j++) {
                byte b1 = (byte) ((random[j] & 0xf0) >> 4);
                byte b2 = (byte) (random[j] & 0x0f);
                if (b1 < 10)
                    buffer.append((char) ('0' + b1));
                    buffer.append((char) ('A' + (b1 - 10)));
                if (b2 < 10)
                    buffer.append((char) ('0' + b2));
                    buffer.append((char) ('A' + (b2 - 10)));

        if (route != null && route.length() > 0) {
        } else {
            String jvmRoute = getJvmRoute();
            if (jvmRoute != null && jvmRoute.length() > 0) {

        return buffer.toString();

This is tomcat’s logic for generating sessionId.


Spring security uses SessionAuthenticationStrategy to process related session after logging in successfully. If servlet is 3.1+,use ChangeSessionAuthenticationStrategy to replace sessionId to prevent sessionFixationAttachments.