HTTP Session Fixation
Understanding Session Fixation
Session fixation is an attack where an attacker fixes (sets) a user's session identifier before the user logs in, then hijacks the session after the user authenticates. This attack exploits applications that don't regenerate session IDs upon authentication.
Unlike session hijacking where attackers steal existing session IDs, session fixation involves the attacker providing the session ID to the victim, making it particularly dangerous in scenarios where session IDs can be set through URLs or other means.
Key Concept: Session fixation succeeds when an application accepts session IDs from untrusted sources and fails to regenerate them upon authentication.
How Session Fixation Works
The attack typically follows these steps:
1. Attacker Obtains Valid Session ID
The attacker visits the target application and obtains a valid session identifier:
GET /login HTTP/1.1
Host: vulnerable-app.com
HTTP/1.1 200 OK
Set-Cookie: SESSIONID=ABC123; Path=/; HttpOnly
2. Attacker Fixes Victim's Session
The attacker tricks the victim into using the known session ID through various methods:
URL-based Session Fixation
# Attacker sends victim a link with fixed session ID
https://vulnerable-app.com/login?SESSIONID=ABC123
Cookie-based Session Fixation
<!-- Attacker hosts malicious page that sets cookie -->
<script>
document.cookie = "SESSIONID=ABC123; domain=.vulnerable-app.com; path=/";
window.location = "https://vulnerable-app.com/login";
</script>
Meta Tag Session Fixation
<!-- If application accepts session ID via meta refresh -->
<meta http-equiv="Set-Cookie" content="SESSIONID=ABC123; path=/">
3. Victim Authenticates
The victim logs in using the fixed session ID. If the application doesn't regenerate the session ID upon authentication, the session remains valid with the attacker-known identifier.
4. Attacker Hijacks Session
The attacker uses the known session ID to access the victim's authenticated session:
GET /account HTTP/1.1
Host: vulnerable-app.com
Cookie: SESSIONID=ABC123
# Attacker now has access to victim's account
Attack Vectors and Techniques
Cross-Site Session Fixation
Using cross-site scripting or malicious websites to set session cookies for the target domain:
<!-- Malicious site sets cookie for target domain -->
<iframe src="https://vulnerable-app.com/set-session?id=FIXED123"></iframe>
<script>
// Redirect victim to login page
setTimeout(() => {
window.location = "https://vulnerable-app.com/login";
}, 1000);
</script>
Social Engineering Session Fixation
Tricking users into clicking links with fixed session IDs through phishing emails or social media:
Subject: Important Security Update Required
Dear User,
Please log in immediately to update your security settings:
https://legitimate-bank.com/login?sessionid=ATTACKER_CONTROLLED_ID
Best regards,
Security Team
Network-Level Session Fixation
In unsecured networks, attackers might intercept and modify HTTP responses to inject session IDs:
# Attacker modifies response in transit
HTTP/1.1 200 OK
Set-Cookie: SESSIONID=ATTACKER_KNOWN_ID; Path=/; HttpOnly
Content-Type: text/html
<html>...</html>
Session Fixation via Form Fields
Some applications accept session IDs through hidden form fields:
<form action="/login" method="post">
<input type="hidden" name="sessionid" value="FIXED_SESSION_ID">
<input type="text" name="username">
<input type="password" name="password">
<input type="submit" value="Login">
</form>
Warning: Session fixation attacks can be combined with other techniques like XSS or CSRF to increase their effectiveness and bypass some security measures.
Impact and Consequences
Account Takeover
Successful session fixation leads to complete account takeover, allowing attackers to:
- Access sensitive personal information
- Perform actions on behalf of the victim
- Modify account settings and passwords
- Access financial information and perform transactions
Privilege Escalation
If the victim has administrative privileges, session fixation can lead to:
- Administrative access to the application
- Access to other users' data
- System configuration changes
- Data exfiltration on a large scale
Persistent Access
Unlike some other attacks, session fixation can provide persistent access until:
- The session expires naturally
- The user explicitly logs out
- The application invalidates the session
Defense Strategies
Session ID Regeneration
The most effective defense is to regenerate session IDs upon authentication:
// PHP example
session_start();
if (authenticate_user($username, $password)) {
session_regenerate_id(true); // Delete old session
$_SESSION['user_id'] = $user_id;
$_SESSION['authenticated'] = true;
}
// Node.js example
app.post('/login', (req, res) => {
if (authenticateUser(req.body.username, req.body.password)) {
req.session.regenerate((err) => {
if (err) throw err;
req.session.userId = user.id;
req.session.authenticated = true;
req.session.save();
});
}
});
Reject External Session IDs
Don't accept session IDs from URLs, form fields, or other external sources:
// Only accept session IDs from cookies
if (isset($_GET['sessionid']) || isset($_POST['sessionid'])) {
// Ignore external session ID attempts
unset($_GET['sessionid']);
unset($_POST['sessionid']);
}
// Validate session ID format
if (!preg_match('/^[a-zA-Z0-9]{32}$/', $session_id)) {
// Invalid session ID format
session_regenerate_id(true);
}
Secure Session Configuration
Configure sessions with security-focused settings:
// PHP session configuration
ini_set('session.cookie_httponly', 1);
ini_set('session.cookie_secure', 1);
ini_set('session.cookie_samesite', 'Strict');
ini_set('session.use_only_cookies', 1);
ini_set('session.use_strict_mode', 1);
// Express.js session configuration
app.use(session({
secret: 'strong-secret-key',
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'strict',
maxAge: 1800000 // 30 minutes
}
}));
Additional Authentication Checks
Implement additional checks to detect session fixation attempts:
// Check for session characteristics changes
function validateSession($session) {
$current_ip = $_SERVER['REMOTE_ADDR'];
$current_ua = $_SERVER['HTTP_USER_AGENT'];
if (isset($_SESSION['ip_address']) && $_SESSION['ip_address'] !== $current_ip) {
// IP address changed - potential session hijacking
session_destroy();
return false;
}
if (isset($_SESSION['user_agent']) && $_SESSION['user_agent'] !== $current_ua) {
// User agent changed - potential session hijacking
session_destroy();
return false;
}
return true;
}
Session Timeout and Rotation
Implement appropriate session timeouts and periodic rotation:
// Implement session timeout
if (isset($_SESSION['last_activity']) &&
(time() - $_SESSION['last_activity'] > 1800)) {
session_unset();
session_destroy();
}
$_SESSION['last_activity'] = time();
// Periodic session ID regeneration
if (!isset($_SESSION['created'])) {
$_SESSION['created'] = time();
} else if (time() - $_SESSION['created'] > 1800) {
session_regenerate_id(true);
$_SESSION['created'] = time();
}
Content Security Policy
Use CSP to prevent malicious scripts from setting cookies:
Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-random123'; frame-ancestors 'none';
Best Practice: Always regenerate session IDs upon authentication and implement multiple layers of session security. Session fixation is easily preventable with proper session management practices.