HTTP Session Fixation

HTTP Session Fixation Illustration

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.