HIGH session fixationexpress

Session Fixation in Express

How Session Fixation Manifests in Express

Session fixation in Express applications occurs when an attacker can set or predict a victim's session identifier before authentication, allowing them to hijack the session after the victim logs in. This vulnerability is particularly dangerous in Express because of how session middleware handles session IDs by default.

// Vulnerable Express session setup
const express = require('express');
const session = require('express-session');
const app = express();

app.use(session({
  secret: 'keyboard cat',
  resave: false,
  saveUninitialized: true,
  cookie: { secure: false } // HTTP only, no secure flag
}));

The vulnerability manifests in several Express-specific ways:

  • Predictable session IDs: By default, express-session uses a simple incrementing counter or weak random number generator, making session IDs predictable.
  • Uninitialized session creation: With saveUninitialized: true, sessions are created even for unauthenticated users, giving attackers a target.
  • resave: false combined with saveUninitialized: true means sessions persist across requests without authentication.

Common Express-specific attack patterns include:

// Attacker crafts a URL with their session ID
app.get('/login', (req, res) => {
  // Attacker sends victim: http://example.com/login?sessionid=abc123
  if (req.query.sessionid) {
    req.sessionID = req.query.sessionid; // INSECURE: allows session fixation
  }
  res.render('login');
});

Another vulnerability appears in Express applications that expose session IDs through URLs or headers:

// Vulnerable: session ID in URL
app.get('/api/data', (req, res) => {
  const sessionId = req.query.sid; // Attacker-controlled session ID
  // Uses attacker's session instead of creating new one
  req.sessionID = sessionId;
  res.json({ data: getSessionData(sessionId) });
});

Session fixation also occurs when Express applications fail to regenerate sessions after privilege escalation:

// Vulnerable: no session regeneration after login
app.post('/login', (req, res) => {
  const { username, password } = req.body;
  const user = authenticate(username, password);
  if (user) {
    req.session.user = user; // Still using old session ID!
    res.redirect('/dashboard');
  }
});

Express-Specific Detection

Detecting session fixation in Express requires examining both code patterns and runtime behavior. middleBrick's black-box scanning identifies these vulnerabilities without requiring source code access:

Code Pattern Analysis

// middleBrick CLI scan
middlebrick scan https://api.example.com/login --category session-management

The scanner tests for:

  • Session ID predictability through statistical analysis of generated IDs
  • Exposure of session IDs in URLs, headers, or response bodies
  • Missing session regeneration after authentication
  • Unsafe session configuration parameters

Runtime Detection

middleBrick actively tests Express applications by:

# Testing session fixation vulnerability
curl -c cookies.txt "https://api.example.com/login"
# Get initial session ID
SESSION_ID=$(grep -o 'connect\.sid=[^;]*' cookies.txt | cut -d'=' -f2)

# Attempt fixation
curl -b "connect\.sid=$SESSION_ID" "https://api.example.com/login" -c cookies2.txt

# Check if session persisted
FIXATED_ID=$(grep -o 'connect\.sid=[^;]*' cookies2.txt | cut -d'=' -f2)
if [ "$SESSION_ID" = "$FIXATED_ID" ]; then
  echo "Session fixation vulnerability detected"
fi

Configuration Analysis

middleBrick analyzes Express session middleware configuration for risky defaults:

// middleBrick reports these as high-risk configurations
{
  "session_config": {
    "saveUninitialized": true,      // High risk
    "resave": false,                // Medium risk
    "cookie": {
      "secure": false,              // High risk
      "httpOnly": false             // High risk
    }
  }
}

Express-Specific Remediation

Fixing session fixation in Express requires both secure configuration and proper session lifecycle management. Here's the secure Express session setup:

const express = require('express');
const session = require('express-session');
const app = express();

app.use(session({
  secret: process.env.SESSION_SECRET, // Use strong, random secret
  resave: false,
  saveUninitialized: false, // Only create session when needed
  cookie: {
    secure: true,           // Require HTTPS
    httpOnly: true,         // Prevent JS access
    sameSite: 'strict',     // Prevent CSRF
    maxAge: 24 * 60 * 60 * 1000 // 24 hours
  }
}));

Session Regeneration After Authentication

app.post('/login', (req, res, next) => {
  const { username, password } = req.body;
  
  authenticate(username, password)
    .then(user => {
      if (!user) {
        return res.status(401).json({ error: 'Invalid credentials' });
      }
      
      // CRITICAL: Regenerate session to prevent fixation
      req.session.regenerate(err => {
        if (err) return next(err);
        
        req.session.user = user;
        req.session.authenticated = true;
        res.json({ message: 'Login successful' });
      });
    })
    .catch(next);
});

Session Invalidation on Logout

app.post('/logout', (req, res) => {
  // Destroy session completely
  req.session.destroy(err => {
    if (err) return res.status(500).json({ error: 'Logout failed' });
    
    // Clear session cookie
    res.clearCookie('connect.sid');
    res.json({ message: 'Logged out successfully' });
  });
});

Middleware for Session Security

// Custom middleware to prevent session fixation
function sessionSecurity(req, res, next) {
  // Check for session ID in URL parameters
  if (req.query.sessionid || req.query.sid) {
    return res.status(400).json({ 
      error: 'Session ID cannot be provided in URL' 
    });
  }
  
  // Check for session fixation attempts
  if (req.session && req.session.attemptedFixation) {
    return res.status(403).json({ 
      error: 'Suspicious session activity detected' 
    });
  }
  
  next();
}

app.use(sessionSecurity);

Testing Your Fixes

After implementing these fixes, verify with middleBrick's continuous monitoring:

# Pro plan: continuous monitoring
middlebrick monitor https://api.example.com --schedule daily --alert slack

The scanner will attempt session fixation attacks and verify that your session regeneration and configuration changes are effective.

Frequently Asked Questions

Why is session fixation particularly dangerous in Express applications?
Express applications are vulnerable because express-session's default configuration (saveUninitialized: true, resave: false) creates sessions before authentication, making them predictable targets. The middleware's simplicity means developers often overlook session lifecycle management, and the common use of connect.sid cookies makes fixation attacks straightforward to execute.
How does middleBrick detect session fixation without access to source code?
middleBrick uses black-box scanning techniques including statistical analysis of session ID generation patterns, attempting to fixate sessions by setting known IDs, testing for session persistence across authentication boundaries, and analyzing HTTP responses for session ID exposure. The scanner also examines middleware configuration through HTTP headers and response patterns specific to Express applications.