Session Fixation
Session Fixation is a web application security vulnerability that allows attackers to hijack user sessions by forcing victims to authenticate using an attacker-controlled session identifier. This attack exploits the application's failure to regenerate session IDs after successful authentication.
What Is Session Fixation?
Session Fixation is an attack where the attacker obtains or sets a valid session identifier before the victim authenticates, then tricks the victim into using that specific session ID to log in. Once the victim authenticates with the fixed session ID, the attacker can use the same session identifier to gain unauthorized access to the victim's account, bypassing the need to steal credentials or exploit authentication mechanisms.
The vulnerability exists when web applications fail to regenerate session identifiers after a privilege level change, particularly during the authentication process. When a user logs in, the application should invalidate the old session and create a new one with a fresh session ID. If the application reuses the pre-authentication session ID, an attacker who knows that ID can hijack the authenticated session immediately after the victim logs in.
Session Fixation is categorized under A07:2021 – Identification and Authentication Failures in the OWASP Top 10. While less prevalent than some other session-based attacks, it remains a critical vulnerability because it requires minimal technical sophistication to exploit. The attack is particularly dangerous because it can completely bypass authentication without requiring the attacker to know the victim's username or password.
How It Works
The attacker visits the target web application and obtains a valid session identifier. This could be a cookie, URL parameter, or hidden form field. The attacker doesn't need to authenticate; they simply need a session ID that the application recognizes as valid.
The attacker tricks the victim into using this specific session ID. This can be done through various methods: sending a crafted link with the session ID in the URL (e.g., https://bank.com/login?JSESSIONID=abc123), using XSS to set the session cookie, or exploiting subdomain vulnerabilities to inject cookies.
The unsuspecting victim clicks the malicious link or visits the page where the session ID has been set, then proceeds to log in normally using their legitimate credentials. The application authenticates the user but fails to regenerate the session identifier.
After successful authentication, the vulnerable application continues using the same session ID that existed before login. The session is now authenticated and associated with the victim's account, but it's still using the session identifier that the attacker knows and can control.
The attacker uses the known session ID to make authenticated requests to the application. Since the session is now authenticated as the victim, the attacker gains full access to the victim's account without ever knowing their password. The attacker can view sensitive data, perform transactions, or modify account settings.
Vulnerable Code Example
@RestController
public class AuthController {
@Autowired
private UserService userService;
@PostMapping("/login")
public ResponseEntity<?> login(
@RequestBody LoginRequest req,
HttpSession session
) {
User user = userService.authenticate(
req.getUsername(),
req.getPassword()
);
if (user != null) {
// VULNERABLE: Session ID is NOT regenerated after login
// The pre-authentication session ID remains valid
session.setAttribute("userId", user.getId());
session.setAttribute("username", user.getUsername());
session.setAttribute("authenticated", true);
return ResponseEntity.ok(Map.of(
"message", "Login successful",
"user", user.getUsername()
));
}
return ResponseEntity.status(401)
.body("Invalid credentials");
}
}
// Attack scenario:
// 1. Attacker gets session ID: JSESSIONID=attacker-known-id
// 2. Attacker sends victim: https://app.com/login?JSESSIONID=attacker-known-id
// 3. Victim logs in with their credentials
// 4. Session "attacker-known-id" is now authenticated as victim
// 5. Attacker uses JSESSIONID=attacker-known-id to access victim's accountSecure Code Example
@RestController
public class AuthController {
@Autowired
private UserService userService;
@PostMapping("/login")
public ResponseEntity<?> login(
@RequestBody LoginRequest req,
HttpServletRequest request
) {
User user = userService.authenticate(
req.getUsername(),
req.getPassword()
);
if (user != null) {
// SECURE: Get the old session and invalidate it
HttpSession oldSession = request.getSession(false);
if (oldSession != null) {
oldSession.invalidate();
}
// Create a new session with a new session ID
HttpSession newSession = request.getSession(true);
newSession.setAttribute("userId", user.getId());
newSession.setAttribute("username", user.getUsername());
newSession.setAttribute("authenticated", true);
// Alternative: Use changeSessionId() in Servlet 3.1+
// request.changeSessionId();
return ResponseEntity.ok(Map.of(
"message", "Login successful",
"user", user.getUsername()
));
}
return ResponseEntity.status(401)
.body("Invalid credentials");
}
}
// Spring Security provides session fixation protection by default:
// - sessionFixation().newSession() creates a new session
// - sessionFixation().migrateSession() migrates attributes to new session
// - sessionFixation().changeSessionId() changes ID (Servlet 3.1+)Types of Session Fixation
Cookie-Based Session Fixation
The attacker sets the session cookie in the victim's browser through various methods. This can be accomplished via Cross-Site Scripting (XSS) vulnerabilities that allow the attacker to execute JavaScript and set cookies, HTTP Response Splitting (CRLF injection) to inject Set-Cookie headers, or by exploiting subdomain cookie scope where a cookie set on a subdomain (e.g., attacker.example.com) is sent to the main domain (example.com) if not properly scoped.
URL-Based Session Fixation
The session identifier is passed through URL parameters rather than cookies, such as https://app.com/login?JSESSIONID=abc123. The attacker sends the victim a crafted link containing the known session ID. When the application accepts session IDs from URL parameters and doesn't regenerate them after login, the victim authenticates using the attacker's session ID. This type is easier to exploit but also easier to detect and prevent by avoiding URL-based session management entirely.
Cross-Subdomain Session Fixation
Exploits cookie scope rules to set session cookies from attacker-controlled subdomains. If an attacker controls evil.example.com and the session cookie doesn't specify a restrictive domain attribute, the attacker can set a cookie like Set-Cookie: SESSIONID=xyz; Domain=.example.com. This cookie will be sent to all subdomains and the main domain. When the victim logs in at www.example.com, they use the attacker's session ID. Prevention requires proper Domain and Path cookie attributes.
Impact
A successful Session Fixation attack allows an attacker to completely bypass authentication and gain full access to a victim's account. The consequences can be severe and long-lasting.
The attacker gains full access to the victim's authenticated session without knowing their username or password. This allows the attacker to perform any action the victim is authorized to perform, including viewing sensitive data, modifying account settings, making transactions, or accessing private communications.
Unlike some other session attacks, Session Fixation can provide long-term access to the victim's account as long as the session remains valid. The attacker can continue using the hijacked session for the entire session lifetime, which could be hours or days depending on the application's session timeout configuration.
In financial applications, attackers can initiate unauthorized transactions, transfer funds, or steal sensitive financial information. In e-commerce applications, they can place orders, change shipping addresses, or access stored payment methods. In healthcare or government applications, they can access highly sensitive personal information.
Session Fixation attacks are difficult to detect because the attacker's actions appear to come from the victim's legitimate session. Audit logs show the victim's authenticated session performing actions, making it hard to distinguish between legitimate user activity and attacker activity. This can complicate incident response and forensic investigations.
Prevention Checklist
Always invalidate the old session and create a new one with a fresh session identifier after successful login. In Java/Servlet, use request.changeSessionId() or invalidate the old session and create a new one. In Spring Security, session fixation protection is enabled by default. In PHP, use session_regenerate_id(true). This is the primary defense against Session Fixation.
Never accept session identifiers through URL parameters or GET requests. Session IDs should only be transmitted through secure, HTTP-only cookies. Disable URL rewriting for session IDs in your application server configuration. In Tomcat/Spring Boot, ensure URL encoding is disabled to prevent JSESSIONID from appearing in URLs.
Set session cookies with Secure, HttpOnly, and SameSite attributes. The Secure flag ensures cookies are only sent over HTTPS. HttpOnly prevents JavaScript access, mitigating XSS-based cookie injection. SameSite=Strict or SameSite=Lax prevents cross-site cookie transmission. Additionally, set restrictive Domain and Path attributes to limit cookie scope.
Configure appropriate session timeout values to limit the window of opportunity for attackers. Use both idle timeout (invalidate sessions after inactivity) and absolute timeout (invalidate sessions after a maximum lifetime regardless of activity). This limits the damage from a successful Session Fixation attack by ensuring hijacked sessions eventually expire.
Bind sessions to additional metadata such as User-Agent, IP address, or client fingerprints. While these can change legitimately, sudden changes may indicate session hijacking. Implement anomaly detection to flag suspicious changes in session context. Be cautious with IP validation as legitimate users may have changing IPs (mobile networks, VPNs), but major discrepancies should trigger re-authentication.
Since Session Fixation often relies on XSS or subdomain cookie injection, implement comprehensive XSS prevention through input validation, output encoding, and Content Security Policy (CSP). Properly configure cookie domain attributes to prevent subdomain cookie injection. Ensure all subdomains are under your control and properly secured, or use host-only cookies by omitting the Domain attribute.
Real-World Examples
PayPal Session Fixation
Security researchers discovered a Session Fixation vulnerability in PayPal's authentication flow. The vulnerability allowed attackers to set session identifiers before authentication that remained valid after login, potentially enabling account takeover. PayPal responded by implementing proper session regeneration and additional security measures to prevent session fixation attacks across their platform.
WordPress Session Fixation
A Session Fixation vulnerability was discovered in WordPress's authentication mechanism that affected versions prior to 3.5.1. The vulnerability allowed attackers to hijack user sessions by fixing session cookies before authentication. WordPress released a security update that implemented proper session regeneration during login to prevent the attack vector, affecting millions of WordPress installations worldwide.
Joomla CMS Session Fixation
The popular Joomla content management system was found vulnerable to Session Fixation attacks due to improper session handling during the authentication process. Attackers could craft malicious URLs containing fixed session identifiers and trick administrators into logging in, potentially granting attackers full administrative access to Joomla websites. The vulnerability was patched in subsequent releases with proper session regeneration.
Apache Tomcat Session Management
Several web applications running on Apache Tomcat were found vulnerable to Session Fixation due to improper session configuration and URL-based session tracking. Applications that accepted JSESSIONID from URL parameters and didn't regenerate sessions after login were exploitable. This led to widespread security advisories and best practice recommendations for Tomcat-based applications to disable URL session tracking and implement proper session lifecycle management.
Ready to Test Your Knowledge?
Put what you have learned into practice. Try identifying and fixing Session Fixation vulnerabilities in our interactive coding challenges, or explore more security guides to deepen your understanding.