HIGH credential stuffingexpressbearer tokens

Credential Stuffing in Express with Bearer Tokens

Credential Stuffing in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Credential stuffing is an automated attack technique where lists of breached username and password pairs are used to gain unauthorized access to user accounts. When an Express API relies solely on Bearer tokens for authentication without additional protections, the risk of successful credential stuffing increases if token issuance is not tightly bound to strong authentication and anti-automation controls.

In Express, a typical Bearer token flow might expose this vulnerability when token validation is performed but the endpoint that authenticates users (e.g., /login) does not enforce rate limits or other bot-mitigation strategies. For example, an attacker can use automated scripts to submit many credential pairs and, upon successful authentication, receive a valid Bearer token. Once obtained, the attacker can reuse these tokens to call protected endpoints such as /api/me or /api/transactions. Because Bearer tokens are often stored in headers and accepted without additional context checks, an attacker can rotate through valid tokens and bypass IP-based session limits if token revocation is not implemented.

Another specific risk arises when Express applications accept Bearer tokens in URLs or logs, which can lead to accidental leakage and make token replay easier for attackers. If the application issues long-lived tokens or does not require re-authentication for sensitive operations, credential stuffing can lead to account takeover even when the initial credential validation appears normal. Attackers may also probe for weak token generation algorithms or predictable token values, which can compound the risk.

It is important to note that middleBrick scans this attack surface by running checks such as Authentication and BOLA/IDOR in parallel, detecting whether token issuance is over-permissive or whether endpoints accept Bearer tokens without sufficient rate limiting or anomaly detection. These scans help identify whether your Express API exposes endpoints that could be leveraged in a credential stuffing campaign, without making assumptions about internal infrastructure.

Bearer Tokens-Specific Remediation in Express — concrete code fixes

To reduce the risk of credential stuffing when using Bearer tokens in Express, implement strong authentication controls, token binding, and rate limiting. Below are concrete code examples that demonstrate secure practices.

1. Enforce strong authentication before issuing tokens

Ensure that the login endpoint applies rate limiting and requires multi-factor authentication for high-risk scenarios.

const express = require('express');
const rateLimit = require('express-rate-limit');
const jwt = require('jsonwebtoken');

const app = express();
app.use(express.json());

// Apply rate limiting to the login endpoint to deter credential stuffing
const loginLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 5, // limit each IP to 5 login requests per window
  message: { error: 'Too many login attempts. Please try again later.' }
});

app.post('/login', loginLimiter, async (req, res) => {
  const { username, password } = req.body;
  // Replace with secure user lookup and password verification
  const user = await findUserByUsername(username);
  if (!user || !(await verifyPassword(password, user.passwordHash))) {
    return res.status(401).json({ error: 'Invalid credentials' });
  }

  // Issue a short-lived Bearer token and include minimal claims
  const token = jwt.sign(
    {
      sub: user.id,
      role: user.role,
      // Avoid including sensitive data in the token payload
    },
    process.env.JWT_SECRET,
    { expiresIn: '15m', issuer: 'your-service', audience: 'your-api-audience' }
  );

  res.json({ access_token: token, token_type: 'Bearer', expires_in: 900 });
});

2. Validate Bearer tokens on protected routes with proper error handling

Use middleware that verifies the token signature, checks the issuer and audience, and rejects malformed tokens without leaking details.

const jwt = require('jsonwebtoken');

function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

  if (!token) {
    return res.status(401).json({ error: 'Access token required' });
  }

  jwt.verify(token, process.env.JWT_SECRET, {
    issuer: 'your-service',
    audience: 'your-api-audience',
    algorithms: ['HS256']
  }, (err, decoded) => {
    if (err) {
      return res.status(403).json({ error: 'Invalid or expired token' });
    }
    req.user = decoded;
    next();
  });
}

app.get('/api/me', authenticateToken, (req, res) => {
  // Use req.user.sub to access the user identifier
  res.json({ user_id: req.user.sub, role: req.user.role });
});

3. Implement token revocation and reuse detection

For sensitive operations, consider short token lifetimes and a denylist or one-time-use tracking to reduce the window for replay attacks.

const revokedTokens = new Set(); // In production, use a fast, shared store

function revokeToken(token) {
  revokedTokens.add(token);
}

function isTokenRevoked(token) {
  return revokedTokens.has(token);
}

// Example usage in logout
app.post('/logout', authenticateToken, (req, res) => {
  const token = req.headers['authorization'].split(' ')[1];
  revokeToken(token);
  res.json({ message: 'Logged out' });
});

4. Avoid exposing tokens in URLs and logs

Ensure tokens are transmitted only via the Authorization header and are not written to logs or URLs where they might be leaked.

// Do NOT log tokens
app.use((req, res, next) => {
  const auth = req.headers['authorization'];
  if (auth) {
    // Redact token from logs
    console.log(`Request: ${req.method} ${req.url} Authorization: ${auth.replace(/\S+$/, '****')}`);
  } else {
    console.log(`Request: ${req.method} ${req.url}`);
  }
  next();
});

By combining rate limiting on authentication endpoints, strict token validation, short lifetimes, and careful handling of token data, you can significantly reduce the risk of credential stuffing compromising accounts that use Bearer tokens in Express.

Frequently Asked Questions

Does middleBrick fix credential stuffing vulnerabilities in Express?
middleBrick detects and reports credential stuffing risks such as missing rate limits on authentication endpoints and unsafe Bearer token handling. It provides remediation guidance but does not automatically fix or block requests.
Can I test my Express API for Bearer token issues using the free plan?
Yes, the free plan includes 3 scans per month, which is sufficient for initial checks of authentication and token handling in Express APIs.