Unrestricted Resource Consumption

Unrestricted Resource Consumption in Node.js Express [CVE-2026-33169]

[March 2026] Updated CVE-2026-33169

Overview

Unrestricted Resource Consumption vulnerabilities occur when an input-triggered operation (such as a regular expression with complex backtracking) can cause CPU-time growth that is quadratic or worse in relation to the input length. CVE-2026-33169 affects Ruby's Active Support: its NumberToDelimitedConverter uses a lookahead-based regex with gsub! to insert thousands delimiters, and the interaction with a repeated lookahead group caused quadratic time on long digit strings. The patch versions 8.1.2.1, 8.0.4.1, and 7.2.3.1 mitigate this by correcting the regex or its usage. In Node.js (Express) contexts, a similar pattern can arise if server-side formatting or input validation uses a complex, backtracking-prone regex on large user-supplied strings. An attacker could send long numeric inputs to trigger excessive CPU usage, causing Denial of Service via resource exhaustion. While CVE-2026-33169 is specific to Ruby, the underlying vulnerability class-catastrophic backtracking in regex or heavy repeated pattern evaluation-is language-agnostic and can manifest in JavaScript as well. To defend in an Express app, avoid heavy or backtracking-prone regex patterns for critical paths (e.g., numeric formatting). Prefer safe implementations (Intl.NumberFormat, or a linear-time manual grouping algorithm), validate input size, apply rate limits and request-body size caps, and instrument resource usage to detect spikes. Patch dependencies promptly and apply the fixed versions to any libraries that reproduce this pattern, or implement equivalent safe logic if the library is not patchable.

Affected Versions

Affected versions (Active Support): < 8.1.2.1, < 8.0.4.1, < 7.2.3.1; fixed in 8.1.2.1, 8.0.4.1, 7.2.3.1.

Code Fix Example

Node.js (Express) API Security Remediation
/* Vulnerable pattern: uses a lookahead-based grouping regex that can backtrack heavily on long inputs */
function formatVulnerable(n) {
  return String(n).replace(/\\B(?=(\\d{3})+(?!\\d))/g, ',');
}

/* Safe fix: avoid heavy regex; use Intl or manual grouping */
function formatSafe(n) {
  // Preferred: use Intl for proper locale-aware grouping
  if (typeof Intl !== 'undefined' && Intl.NumberFormat) {
    return Number(n).toLocaleString('en-US');
  }
  // Fallback: manual, linear-time grouping
  const s = String(n);
  let out = '';
  let count = 0;
  for (let i = s.length - 1; i >= 0; i--) {
    out = s[i] + out;
    count++;
    if (count === 3 && i > 0) {
      out = ',' + out;
      count = 0;
    }
  }
  return out;
}

console.log('vulnerable:', formatVulnerable('1234567890123456'));
console.log('safe:', formatSafe('1234567890123456'));

CVE References

Choose which optional cookies to allow. You can change this any time.