Outdated Date Library Can Be Used to Slow Down or Crash Your Application

Your application uses an outdated version of Moment.js — a popular tool developers use to handle dates and times. This version has a known flaw where sending it an unusually long piece of text can cause it to get stuck processing, slowing your app to a crawl or making it temporarily unavailable to users. This only matters if your app accepts date input directly from users or external sources.

Business Impact And Actions

high urgency

Business Impact

If your application accepts user-submitted date strings (e.g., form fields, API inputs) and passes them to Moment.js without length checks, an attacker could deliberately send crafted input to make your app unresponsive. This could result in service downtime, failed customer transactions, and potential SLA breaches. Additionally, Moment.js has been officially declared a legacy project by its own maintainers since 2020, meaning it will receive no new features or long-term security investment — making this a good time to plan a migration.

What To Do

  1. Ask your developer to upgrade Moment.js to version 2.29.4 or later — this is a straightforward package update that typically takes under an hour.
  2. If an immediate upgrade isn't possible, ask your developer to add a simple length check so that any user-submitted date strings longer than 200 characters are rejected before reaching the library.
  3. Consider planning a longer-term migration away from Moment.js to a modern alternative like Luxon or Day.js, as Moment.js is no longer actively developed.
  4. If your application does not accept date strings from users or external systems, your exposure is minimal — confirm this with your developer.

Moment.js 2.19.3 ReDoS via preprocessRFC2822() — CVE-2022-31129

high severity

Vulnerability Explanation

The vulnerability exists in Moment.js's RFC2822 date string parser. When moment() is called with a user-supplied string and no explicit format is provided, it attempts RFC2822 parsing by default via the preprocessRFC2822() function. The regex used to strip legacy comments (content inside parentheses) from the date string has quadratic (N²) complexity due to catastrophic backtracking. Inputs above ~10k characters cause a noticeable slowdown; inputs with hundreds of thousands of repeated parentheses (e.g., '('.repeat(500000)) can block the Node.js event loop for minutes, effectively causing a denial-of-service.

Root Cause

The preprocessRFC2822() function in from-string.js used a regex pattern with greedy quantifiers that caused catastrophic backtracking when processing specific inputs — particularly strings with many consecutive opening parentheses. Because RFC2822 parsing is attempted by default when no format is specified, any code path that calls moment(userInput) without an explicit format string is potentially vulnerable.

Technical Impact

An unauthenticated attacker who can supply a string to any endpoint that passes it to the moment() constructor (without an explicit format argument) can block the Node.js event loop, causing the application to become unresponsive for all users. This is a network-reachable, no-privileges-required denial-of-service. No data is exposed or modified.

Severity Justification

CVSS 3.1 score of 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H). Network-reachable, no authentication required, no user interaction needed. Impact is limited to availability — no confidentiality or integrity impact. Exploitability is realistic wherever user-controlled strings reach the moment() constructor without length validation.

Affected Components

  • moment >= 2.18.0 < 2.29.4

Remediation Steps

  1. Upgrade moment to 2.29.4 or later: run `npm install moment@latest` (or `yarn add moment@latest`). This is the primary fix — the patch rewrites the RFC2822 regex to eliminate the quadratic complexity.
  2. If you cannot upgrade immediately, add an input length guard before any call to moment() with user-supplied data: reject or truncate strings longer than 200 characters.
  3. Audit your codebase for all calls to moment(userInput) where no explicit format string is passed as the second argument — these are the vulnerable call sites.
  4. Consider migrating to an actively maintained alternative (Luxon, Day.js, or date-fns). Moment.js has been in maintenance-only mode since 2020 and will not receive new features or proactive security work.
  5. After upgrading, run your existing test suite to confirm date-handling behaviour is unchanged — the 2.29.4 patch is backward-compatible for standard usage.

Verification Steps

  1. Run `npm list moment` or `cat node_modules/moment/package.json | grep '"version"'` to confirm the installed version is 2.29.4 or later.
  2. Run `node -e "const m = require('moment'); console.log(m.version);"` to verify the runtime version.
  3. Optionally, test the fix: `node -e "const m = require('moment'); console.time('t'); m('('.repeat(10000)); console.timeEnd('t');"` — on the patched version this should complete in milliseconds, not minutes.

Best Practices

  • Always pass an explicit format string as the second argument to moment() when parsing user-supplied input (e.g., moment(input, 'YYYY-MM-DD')) — this bypasses RFC2822 auto-detection entirely.
  • Validate and cap the length of any user-supplied date string to 200 characters or fewer before passing it to any date parsing library.
  • Pin third-party library versions in package.json and run automated dependency audits (e.g., `npm audit`) in your CI pipeline to catch known CVEs before they reach production.
  • For new projects or major refactors, prefer actively maintained date libraries such as Luxon, Day.js, or date-fns over Moment.js.

Found this in your infrastructure?

VulWall scans for this and dozens of other issues automatically.

Scan Your Domain Free