Redis Session Security Guide

Share

To secure Redis sessions, you need to: (1) use TLS connections to Redis in production, (2) regenerate session IDs after login to prevent session fixation attacks, (3) set cookies as httpOnly and secure with proper sameSite settings, (4) configure appropriate session TTLs, and (5) use a strong session secret (32+ characters). This blueprint ensures session management follows security best practices for server-side storage.

Setup Time1-2 hours

TL;DR

Redis sessions are faster than database sessions but require secure configuration. Use TLS connections, generate cryptographically secure session IDs, implement session rotation on authentication state changes, and set proper TTLs to limit session lifetime.

Express Session with Redis Redis

server/session.ts
import session from 'express-session'
import RedisStore from 'connect-redis'
import { createClient } from 'redis'

// Secure Redis connection
const redisClient = createClient({
  url: process.env.REDIS_URL,
  socket: {
    tls: process.env.NODE_ENV === 'production',
    rejectUnauthorized: true,
  },
})

await redisClient.connect()

export const sessionMiddleware = session({
  store: new RedisStore({ client: redisClient }),
  secret: process.env.SESSION_SECRET!,  // 32+ characters
  name: 'sessionId',  // Don't use default 'connect.sid'
  resave: false,
  saveUninitialized: false,
  cookie: {
    secure: process.env.NODE_ENV === 'production',
    httpOnly: true,
    sameSite: 'lax',
    maxAge: 1000 * 60 * 60 * 24,  // 24 hours
  },
})

Session Rotation

server/auth.ts
import { Request, Response, NextFunction } from 'express'

export async function login(req: Request, res: Response) {
  // Verify credentials...
  const user = await verifyCredentials(req.body)

  if (!user) {
    return res.status(401).json({ error: 'Invalid credentials' })
  }

  // CRITICAL: Regenerate session ID after login
  // Prevents session fixation attacks
  req.session.regenerate((err) => {
    if (err) {
      return res.status(500).json({ error: 'Session error' })
    }

    req.session.userId = user.id
    req.session.loginTime = Date.now()

    res.json({ success: true })
  })
}

export async function logout(req: Request, res: Response) {
  req.session.destroy((err) => {
    if (err) {
      return res.status(500).json({ error: 'Logout failed' })
    }
    res.clearCookie('sessionId')
    res.json({ success: true })
  })
}

Session Validation Middleware

server/middleware/auth.ts
export function requireAuth(req: Request, res: Response, next: NextFunction) {
  if (!req.session.userId) {
    return res.status(401).json({ error: 'Not authenticated' })
  }

  // Optional: Check session age for sensitive operations
  const sessionAge = Date.now() - (req.session.loginTime || 0)
  const maxAge = 1000 * 60 * 30  // 30 minutes for sensitive ops

  if (req.path.includes('/sensitive') && sessionAge > maxAge) {
    return res.status(401).json({ error: 'Please re-authenticate' })
  }

  next()
}

// For very sensitive operations, require re-authentication
export function requireRecentAuth(maxAgeMs = 1000 * 60 * 5) {
  return (req: Request, res: Response, next: NextFunction) => {
    const sessionAge = Date.now() - (req.session.loginTime || 0)

    if (sessionAge > maxAgeMs) {
      return res.status(401).json({
        error: 'Please re-authenticate for this operation',
        requireReauth: true,
      })
    }

    next()
  }
}

Always regenerate session ID after login. Session fixation attacks trick users into authenticating with attacker-controlled session IDs. Regenerating prevents this.

Security Checklist

Pre-Launch Checklist

Redis connection uses TLS

Session ID regenerated on login

Cookies are httpOnly and secure

Session TTL configured

Session secret is strong (32+ chars)

NextAuth + Prisma Database Sessions Clerk Managed Sessions OAuth Token Management

Check Your Session Security

Scan for session vulnerabilities.

Start Free Scan
Security Blueprints

Redis Session Security Guide