HIGH replay attackjwt tokens

Replay Attack with Jwt Tokens

How Replay Attack Manifests in Jwt Tokens

Replay attacks in JWT tokens occur when an attacker intercepts a valid token and uses it to impersonate the legitimate user without needing to compromise the token's cryptographic signature. This attack vector is particularly dangerous because the intercepted JWT appears completely valid to the receiving server.

// Intercepted JWT token from network traffic or XSS attack
const stolenJwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluIiwicm9sZSI6InN1cGVydXNlciIsImlhdCI6MTY0MjE5MDI0NX0.fakeSignature';

// Attacker uses the stolen token
fetch('https://api.example.com/protected', {
  headers: {
    'Authorization': `Bearer ${stolenJwt}`
  }
});

The core vulnerability stems from JWT tokens lacking built-in expiration enforcement mechanisms. While JWTs contain an exp claim for expiration, servers must explicitly validate this claim. Many implementations fail to check expiration, allowing indefinitely valid tokens.

// VULNERABLE: Missing expiration check
const token = jwt.verify(req.headers.authorization.split(' ')[1], secret); // No exp validation
// Attacker can replay this token anytime

Replay attacks become more severe when combined with JWT's stateless nature. Unlike session-based authentication where servers can maintain token revocation lists, JWT tokens cannot be invalidated once issued without additional infrastructure.

// No built-in revocation mechanism
// Once issued, JWT remains valid until expiration
const validJwt = jwt.sign({
  userId: '123',
  role: 'admin'
}, process.env.JWT_SECRET, { expiresIn: '1h' });

// Attacker steals this token and uses it within 1 hour

Network-level vulnerabilities amplify replay attack risks. JWT tokens transmitted over HTTP can be captured via man-in-the-middle attacks, packet sniffing, or through browser storage compromise (localStorage, sessionStorage).

// Vulnerable storage - XSS can steal tokens
localStorage.setItem('jwt_token', validJwt);
// Attacker uses XSS to retrieve and replay

Jwt Tokens-Specific Detection

Detecting replay attack vulnerabilities in JWT implementations requires examining both token validation logic and transmission security. middleBrick's JWT-specific scanner identifies these patterns across 12 security checks.

Detection MethodImplementation CheckRisk Level
Expiration ValidationVerifies exp claim is checked during token verificationHigh
Secure TransmissionEnsures HTTPS-only JWT transmissionCritical
Storage SecurityChecks for unsafe JWT storage (localStorage, cookies without HttpOnly)High
Token RotationDetects absence of refresh token mechanismsMedium
Revocation SupportIdentifies lack of token blacklisting capabilityMedium

middleBrick's active scanning tests JWT endpoints by attempting replay attacks with captured tokens. The scanner verifies whether servers properly validate token expiration and reject replayed tokens.

# middleBrick CLI scan for JWT replay vulnerabilities
middlebrick scan https://api.example.com/auth

# Output includes JWT-specific findings:
# - Missing expiration validation
# - Insecure token storage detected
# - No refresh token implementation
# - Weak token rotation strategy

The scanner also examines OpenAPI specifications for JWT-related endpoints, checking for proper security scheme definitions and validation requirements.

# OpenAPI spec analysis for JWT security
security:
  - BearerAuth: []
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

middleBrick's LLM security checks extend to AI-powered JWT implementations, detecting prompt injection vulnerabilities that could expose token generation logic or secret keys.

Jwt Tokens-Specific Remediation

Securing JWT implementations against replay attacks requires multiple defensive layers. The most critical remediation is proper expiration validation with minimal token lifetimes.

// SECURE: Short-lived JWT with strict expiration
const jwt = require('jsonwebtoken');

function generateSecureJwt(payload) {
  return jwt.sign(payload, process.env.JWT_SECRET, {
    expiresIn: '15m', // Short lifetime reduces replay window
    issuer: 'your-domain.com',
    audience: 'your-api'
  });
}

// Always validate expiration on verification
function verifyJwt(token) {
  try {
    return jwt.verify(token, process.env.JWT_SECRET, {
      maxAge: '15m', // Enforce strict expiration
      issuer: 'your-domain.com',
      audience: 'your-api'
    });
  } catch (error) {
    // Handle expired, invalid, or replayed tokens
    if (error.name === 'TokenExpiredError') {
      throw new Error('Token expired');
    }
    throw new Error('Invalid token');
  }
}

Implement refresh token mechanisms to maintain user sessions while minimizing replay attack windows for access tokens.

// Refresh token pattern - rotate access tokens
const refreshTokens = new Map();

async function login(username, password) {
  const user = await authenticateUser(username, password);
  
  // Short-lived access token
  const accessToken = jwt.sign(
    { userId: user.id, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: '15m' }
  );
  
  // Long-lived refresh token (secure storage only)
  const refreshToken = jwt.sign(
    { userId: user.id, version: user.tokenVersion },
    process.env.REFRESH_SECRET,
    { expiresIn: '7d' }
  );
  
  refreshTokens.set(refreshToken, user.id);
  return { accessToken, refreshToken };
}

async function refreshAccessToken(refreshToken) {
  if (!refreshTokens.has(refreshToken)) {
    throw new Error('Invalid refresh token');
  }
  
  const decoded = jwt.verify(refreshToken, process.env.REFRESH_SECRET);
  const user = await getUserById(decoded.userId);
  
  // Check if user's token was invalidated
  if (user.tokenVersion !== decoded.version) {
    throw new Error('Token version mismatch');
  }
  
  return generateSecureJwt({ userId: user.id, role: user.role });
}

Enforce HTTPS-only transmission and secure storage practices to prevent token interception.

// Secure JWT handling
// 1. Always use HTTPS
// 2. Store refresh tokens in HttpOnly cookies
// 3. Never store access tokens in localStorage
// 4. Implement token rotation
// 5. Use SameSite cookies for refresh tokens

// HttpOnly cookie for refresh token
res.cookie('refreshToken', refreshToken, {
  httpOnly: true,
  secure: true,
  sameSite: 'strict',
  maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days
});

middleBrick's Pro plan includes continuous monitoring that automatically scans your JWT endpoints for replay attack vulnerabilities, alerting you when security scores drop below configured thresholds.

Frequently Asked Questions

Can JWT tokens be completely prevented from replay attacks?
No, JWT tokens cannot be completely prevented from replay attacks due to their stateless nature. However, you can significantly reduce the risk by implementing short expiration times (15 minutes), refresh token mechanisms, HTTPS-only transmission, and proper revocation systems. middleBrick's scanner helps identify if your implementation has adequate protections against replay attacks.
How does middleBrick detect JWT replay attack vulnerabilities?
middleBrick actively tests JWT endpoints by attempting replay attacks with captured tokens and examining your implementation's response. It checks for missing expiration validation, insecure token storage, lack of refresh token mechanisms, and improper HTTPS enforcement. The scanner provides specific findings with severity levels and remediation guidance for each vulnerability discovered.