HIGH regex dosexpressbearer tokens

Regex Dos in Express with Bearer Tokens

Regex Dos in Express with Bearer Tokens — how this specific combination creates or exposes the vulnerability

A Regular Expression Denial of Service (ReDoS) occurs when an attacker can supply input that causes a regular expression to exhibit catastrophic backtracking, consuming excessive CPU time. In Express applications that use Bearer tokens, this typically happens in two scenarios: route parameter validation and token parsing logic. If your Express app uses a regular expression to validate or extract Bearer tokens from headers, and that regex is poorly constructed, an attacker can send carefully crafted tokens that force the regex engine into exponential-time behavior.

Consider an Express route that attempts to validate a Bearer token format using a vulnerable pattern:

app.get('/api/protected', (req, res) => {
  const authHeader = req.headers.authorization || '';
  const match = authHeader.match(/^Bearer ([a-zA-Z0-9]+)$/);
  if (!match) return res.status(401).send('Unauthorized');
  const token = match[1];
  // ... verify token
});

While this simple pattern is less prone to catastrophic backtracking, more complex token validation regexes—such as those attempting to enforce specific token structures, optional segments, or nested patterns—can become dangerous. For example, a regex intended to validate structured tokens like Bearer abc123.def456.ghi789 might be written with optional groups or repetitions that create overlapping possible matching paths:

// Potentially vulnerable: complex pattern with nested quantifiers
const tokenPattern = /^Bearer (([a-zA-Z0-9\-]+\.)+[a-zA-Z0-9\-]+)$/;
const match = authHeader.match(tokenPattern);

An attacker can craft a long string with repeated segments (e.g., Bearer a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a.a) that forces the regex engine to explore many paths due to the nested ([a-zA-Z0-9\-]+\.)+ group. Even though the overall pattern seems reasonable, the combination of nested quantifiers and repeated subpatterns can lead to exponential backtracking as the engine tries different ways to split the input across the dot-separated segments.

Another common scenario involves middleware that parses and validates tokens using overly permissive character classes and quantifiers. For instance, if you use a regex to strip or validate parts of a Bearer token and inadvertently allow ambiguous repetition, the engine can get stuck trying many possible ways to match the same input:

// Risky: character class with adjacent quantifiers can cause backtracking
const sanitizePattern = /(a+)+/;
sanitizePattern.test(tokenPart);

In an Express API security scan performed by middleBrick, such patterns are flagged during the Input Validation and Unsafe Consumption checks. The scanner does not inspect internal implementation details but identifies endpoints that accept Bearer tokens and then evaluates whether runtime behavior matches patterns known to trigger excessive processing. This helps surface hidden ReDoS risks that might not be obvious during code review.

Because Bearer tokens are often passed directly into validation logic, the combination of untrusted input (the token string) and complex regexes creates a reliable attack surface. An attacker can send a single malicious request that causes the event loop to block, leading to increased latency for other requests and potential denial of service. This is particularly concerning in high-throughput APIs where many concurrent requests arrive.

Bearer Tokens-Specific Remediation in Express — concrete code fixes

To mitigate ReDoS risks when working with Bearer tokens in Express, focus on simplifying and bounding your regular expressions, avoiding nested quantifiers, and using non-capturing groups where appropriate. Prefer straightforward character matching with limited repetition, and validate token structure using length and format constraints rather than complex regexes.

First, avoid nested quantifiers and adjacent repetition. Instead of patterns like (a+)+, use a single repetition construct:

// Safer: no nested quantifiers
const safePattern = /a+/;

For Bearer token validation, prefer simple prefix checks and basic format validation rather than deeply nested patterns. If you need to validate JWT-like tokens (three dot-separated segments), use explicit splits and checks instead of a single complex regex:

// Recommended: explicit validation without risky regex backtracking
app.get('/api/protected', (req, res) => {
  const authHeader = req.headers.authorization || '';
  if (!authHeader.startsWith('Bearer ')) {
    return res.status(401).send('Unauthorized');
  }
  const token = authHeader.slice(7); // 'Bearer '.length === 7
  const parts = token.split('.');
  if (parts.length !== 3) {
    return res.status(401).send('Invalid token format');
  }
  // Optionally validate each segment's character set with simple checks
  const [header, payload, signature] = parts;
  if (!/^[A-Za-z0-9\-_]+$/.test(header) || !/^[A-Za-z0-9\-_]+$/.test(payload)) {
    return res.status(401).send('Invalid token characters');
  }
  // ... verify signature and claims
});

If you must use a regex, keep it flat and avoid repetition on unbounded subpatterns. For example, to match a typical token structure without catastrophic backtracking, use:

// Flat pattern with bounded repetition
const tokenPattern = /^Bearer [A-Za-z0-9\-._~+]+$/;
const match = authHeader.match(tokenPattern);
if (!match) return res.status(401).send('Unauthorized');
const token = match[0].slice(7);

Additionally, apply length and rate-limiting controls at the Express middleware layer to reduce the impact of abusive requests:

// Basic rate limiting and length checks
app.use((req, res, next) => {
  const authHeader = req.headers.authorization || '';
  if (authHeader.length > 4096) {
    return res.status(400).send('Header too long');
  }
  next();
});

Using the middleBrick CLI, you can quickly test your endpoints for input validation issues:

middlebrick scan https://api.example.com

In environments where continuous monitoring is needed, the Pro plan allows you to schedule scans and receive alerts when security scores degrade. For CI/CD enforcement, the GitHub Action can fail builds if the risk score drops below your defined threshold, helping prevent risky regex patterns from reaching production.

When integrating with AI coding assistants via the MCP Server, you can initiate scans directly from your development environment to catch problematic patterns early. These approaches complement secure coding practices by providing automated detection alongside manual code reviews.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can a simple Bearer token regex still cause ReDoS?
Yes. Even patterns that look safe can cause catastrophic backtracking when nested quantifiers or ambiguous repetition are present. Always validate tokens with explicit logic or simple, flat regexes.
Does middleBrick fix ReDoS issues in my Express app?
middleBrick detects and reports potential ReDoS patterns and provides remediation guidance. It does not modify code or block requests; you must apply the suggested fixes in your Express application.