Skip to content

Session Fixation

What does this mean ?

Authenticating a user or creating a new user session without invalidating any current session identifiers allows an attacker to steal authenticated sessions.

What can happen ?

Attackers can change the session identifier to a known value by directly constructing cookies from tainted data, allowing the attacker to share the session with the victim. If the session identification is not renewed after the victim authenticates, successful attacks may result in unauthorized access to sensitive information.

Recommendation

Before approving a new user session, invalidate any existing session IDs.

Sample Code

Vulnerable :

if (txtUsr.Text.Equals("james") && txtPwd.Text.Equals("pass1234"))  
{  
    Session["LIn"] = txtU.Text.Trim();  
    Server.Transfer("index.aspx");   
}  
else  
{  
    lblMessage.Text = "Wrong username or password";  
}  

Non Vulnerable :

protected void btnLogin_Handler(object sender, EventArgs e)  
{  

    if (txtUsr.Text.Equals("james") && txtPwd.Text.Equals("pass1234"))  
    {  
        Session["LIn"] = txtU.Text.Trim();  
        string guid = Guid.NewGuid().ToString();  
        Session["AuthToken"] = guid;  
        // now create a new cookie with this guid value  
        Response.Cookies.Add(new HttpCookie("AuthToken", guid));  
    }  
}  

Vulnerable :

public class VulnerableServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        // Check if the user is already logged in
        HttpSession session = request.getSession();
        if (session.getAttribute("username") == null) {
            // User is not logged in, check if a session ID was provided in the request
            String sessionId = request.getParameter("sessionId");
            if (sessionId != null) {
                // A session ID was provided, fix the user's session to this ID
                session.setId(sessionId);
            }
            // Redirect the user to the login page
            response.sendRedirect("login.jsp");
        } else {
            // User is already logged in, display the protected content
            response.getWriter().println("Protected content");
        }
    }
}

Non Vulnerable :

public class NonVulnerableServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        // Check if the user is already logged in
        HttpSession session = request.getSession(true);
        if (session.isNew()) {
            // This is a new session, generate a new session ID
            session.invalidate();
            session = request.getSession(true);
        }
        if (session.getAttribute("username") == null) {
            // User is not logged in, redirect to the login page
            response.sendRedirect("login.jsp");
        } else {
            // User is already logged in, display the protected content
            response.getWriter().println("Protected content");
        }
    }
}

Vulnerable :

session_start();
// Check if the user is already logged in
if (!isset($_SESSION['username'])) {
    // User is not logged in, check if a session ID was provided in the request
    if (isset($_GET['sessionId'])) {
        // A session ID was provided, fix the user's session to this ID
        session_id($_GET['sessionId']);
    }
    // Redirect the user to the login page
    header('Location: login.php');
    exit;
} else {
    // User is already logged in, display the protected content
    echo 'Protected content';
}

Non Vulnerable :

session_start();

// Check if the user is already logged in
if (!isset($_SESSION['username'])) {
    // This is a new session, generate a new session ID
    session_regenerate_id(true);

    // Redirect the user to the login page
    header('Location: login.php');
    exit;
} else {
    // User is already logged in, display the protected content
    echo 'Protected content';
}

Vulnerable :

app.get('/login', function(req, res) {
    // Check if the user is already logged in
    if (req.session.username == null) {
        // User is not logged in, check if a session ID was provided in the request
        var sessionId = req.query.sessionId;
        if (sessionId != null) {
            // A session ID was provided, fix the user's session to this ID
            req.session.id = sessionId;
        }
        // Redirect the user to the login page
        res.redirect('/login.html');
    } else {
        // User is already logged in, display the protected content
        res.send('Protected content');
    }
});

Non Vulnerable :

app.get('/login', function(req, res) {
    // Check if the user is already logged in
    if (req.session.username == null) {
        // This is a new session, generate a new session ID
        req.session.regenerate(function(err) {
            if (err) {
                // An error occurred while regenerating the session
                res.send('Error: ' + err);
            } else {
                // The session has been regenerated, redirect to the login page
                res.redirect('/login.html');
            }
        });
    } else {
        // User is already logged in, display the protected content
        res.send('Protected content');
    }
});

Vulnerable :

func loginHandler(w http.ResponseWriter, r *http.Request) {
    // Check if the user is already logged in
    if r.Context().Value("username") == nil {
        // User is not logged in, check if a session ID was provided in the request
        sessionId := r.URL.Query().Get("sessionId")
        if sessionId != "" {
            // A session ID was provided, fix the user's session to this ID
            http.SetCookie(w, &http.Cookie{
                Name: "sid",
                Value: sessionId,
            })
        }
        // Redirect the user to the login page
        http.Redirect(w, r, "/login", http.StatusFound)
    } else {
        // User is already logged in, display the protected content
        fmt.Fprint(w, "Protected content")
    }
}

Non Vulnerable :

func loginHandler(w http.ResponseWriter, r *http.Request) {
    // Check if the user is already logged in
    if r.Context().Value("username") == nil {
        // This is a new session, generate a new session ID
        session, _ := store.Get(r, "sid")
        session.Options.MaxAge = -1 // delete session cookie
        session.Save(r, w)

        // Redirect the user to the login page
        http.Redirect(w, r, "/login", http.StatusFound)
    } else {
        // User is already logged in, display the protected content
        fmt.Fprint(w, "Protected content")
    }
}

Vulnerable :

class VulnerableController < ApplicationController
    def login
        # Check if the user is already logged in
        if session[:username].nil?
            # User is not logged in, check if a session ID was provided in the request
            if params[:session_id]
                # A session ID was provided, fix the user's session to this ID
                session[:session_id] = params[:session_id]
            end
            # Redirect the user to the login page
            redirect_to '/login'
        else
            # User is already logged in, display the protected content
            render plain: 'Protected content'
        end
    end
end

Non Vulnerable :

class NonVulnerableController < ApplicationController
    def login
        # Check if the user is already logged in
        if session[:username].nil?
            # This is a new session, generate a new session ID
            reset_session

            # Redirect the user to the login page
            redirect_to '/login'
        else
            # User is already logged in, display the protected content
            render plain: 'Protected content'
        end
    end
end

References