Session Fixation in Chi
How Session Fixation Manifests in Chi
Session fixation in Chi occurs when an attacker can force a victim to use a session ID that the attacker knows in advance. Chi's session management, while robust, can be vulnerable if not configured correctly. The most common manifestation is when Chi's default session store (typically memory or file-based) is used without proper session rotation.
Consider this vulnerable Chi pattern:
const chi = require('chi')
const session = require('chi-session')
const app = chi()
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}))
app.post('/login', (req, res) => {
// No session ID regeneration after authentication
const user = authenticate(req.body.username, req.body.password)
req.session.user = user
res.redirect('/dashboard')
})The vulnerability here is that the session ID remains the same before and after authentication. An attacker can create a session, obtain the session ID (via cookie or URL parameter), and trick a victim into using that same session ID. Once the victim logs in, the attacker gains access to the authenticated session.
Chi-specific manifestations include:
- Session IDs passed via URL parameters when using chi-session with URL-based session tracking
- Missing session destruction on logout, allowing session reuse
- Improper handling of concurrent sessions across Chi's middleware chain
- Session fixation through third-party authentication redirects that don't regenerate session IDs
Another Chi-specific scenario involves the use of chi-passport with OAuth providers. If the callback handler doesn't properly destroy the initial session before establishing the authenticated session, an attacker who predicts or obtains the initial session ID can hijack the authenticated session.
Chi-Specific Detection
Detecting session fixation in Chi applications requires both manual code review and automated scanning. middleBrick's API security scanner can identify session fixation vulnerabilities by analyzing the session management patterns in your Chi application.
middleBrick scans for session fixation by:
- Analyzing session creation and authentication flow patterns
- Checking for session ID regeneration after authentication
- Verifying proper session destruction on logout
- Testing for predictable session ID generation
- Scanning for exposed session IDs in URLs or response headers
Manual detection in Chi involves reviewing your middleware configuration and authentication flow:
// Check for these patterns in your Chi app
const session = require('chi-session')
const chi = require('chi')
const app = chi()
// Vulnerable: No session ID regeneration
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false
}))
// Secure: Regenerate session ID after authentication
app.post('/login', (req, res, next) => {
authenticate(req.body.username, req.body.password)
.then(user => {
req.session.regenerate(err => {
if (err) return next(err)
req.session.user = user
res.redirect('/dashboard')
})
})
.catch(next)
})middleBrick's scanner specifically tests for Chi session fixation by attempting to establish a known session ID before authentication and verifying if that same ID persists after successful login. The scanner also checks for Chi-specific session handling patterns that might expose session IDs through logging, error messages, or debug endpoints.
Chi-Specific Remediation
Remediating session fixation in Chi requires implementing proper session lifecycle management. The most critical fix is regenerating the session ID immediately after authentication. Chi provides several approaches to implement this securely.
Using chi-session with proper regeneration:
const chi = require('chi')
const session = require('chi-session')
const app = chi()
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: true,
httpOnly: true,
sameSite: 'strict'
}
}))
// Secure login with session regeneration
app.post('/login', (req, res, next) => {
authenticate(req.body.username, req.body.password)
.then(user => {
// Regenerate session to prevent fixation
req.session.regenerate(err => {
if (err) return next(err)
req.session.user = user
req.session.authenticated = true
res.redirect('/dashboard')
})
})
.catch(next)
})
// Secure logout with session destruction
app.post('/logout', (req, res) => {
req.session.destroy(err => {
if (err) return res.status(500).send('Logout failed')
res.clearCookie('connect.sid')
res.redirect('/login')
})
})For applications using chi-passport, the fix involves destroying the initial session before establishing the authenticated session:
const passport = require('chi-passport')
app.post('/auth/callback', (req, res, next) => {
// Destroy existing session before passport login
req.session.destroy(err => {
if (err) return next(err)
// Passport will create a new session
passport.authenticate('provider', (err, user, info) => {
if (err) return next(err)
if (!user) return res.redirect('/login')
req.logIn(user, err => {
if (err) return next(err)
res.redirect('/dashboard')
})
})(req, res, next)
})
})Additional Chi-specific security measures include using secure cookies with the secure and httpOnly flags, implementing proper session timeouts, and using a robust session store like Redis instead of the default memory store for production applications. middleBrick's Pro plan includes continuous monitoring that can alert you if session fixation vulnerabilities reappear in your Chi application after remediation.