npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

will-it-redos

v0.1.0

Published

Will it ReDoS? Finds the regexes in your code that a malicious input can hang your server with (catastrophic backtracking) — and prints the exact evil string that does it. Parses each pattern, detects exponential/polynomial blowup, and proves it with a li

Readme

will it ReDoS?

Find the regex in your code that one HTTP request can freeze your server with — and the exact string that does it.

npm version CI types license

npx will-it-redos scan .

On July 2, 2019, a single regex — .*.*=.* — took Cloudflare's entire global network offline for 27 minutes. Stack Overflow went down in 2016 for the same reason. The bug is called ReDoS (Regular-expression Denial of Service): a pattern that, on the right input, makes the engine try an exponential number of ways to match — and one short string pins a CPU core at 100% forever.

It hides in regexes that look completely normal:

const TRIM   = /^(\s+)+$/;             // 💥 exponential
const VALID  = /^(\w+\s?)*$/;          // 💥 exponential
const EMAIL  = /^([a-zA-Z0-9]+)*@.../  // 💥 exponential

will-it-redos finds them — and proves it by handing you the input that hangs them.

$ npx will-it-redos check '(a+)+$'

  /(a+)+$/

   WILL ReDoS   exponential backtracking

  Nested quantifier (a `(x+)+` shape). On a long run of the inner character
  followed by a non-match, the engine tries exponentially many ways to split it.

  The input that hangs it:
    "a".repeat(50000) + "!"

  Proof (live, on this machine):
      19 chars        2.9 ms  ▪
      21 chars       11.8 ms  ▪
      23 chars       44.1 ms  ▪
      25 chars      173.7 ms  ▪
      27 chars      725.5 ms  ████████

  ☠  27 characters froze this regex for 726 ms. Imagine that as a request parameter.

That's not a lint rule guessing. It parsed the pattern, found the ambiguity, built the evil string, and timed the catastrophe — right there.

Scan your whole codebase

$ npx will-it-redos scan src --prove

   EXPONENTIAL   src/validate.js:5:21
    /^(\s+)+$/
    Nested quantifier — on a long inner run + a non-match, the engine explodes.
    evil input: " ".repeat(50000) + "!"
    proven: 27 chars hung this regex for 337 ms (exponential)

   POLYNOMIAL   src/parse.js:16:16
    /.*.*=.*/
    Two adjacent unbounded quantifiers over overlapping characters — quadratic.
    evil input: "a".repeat(50000) + "\n"

  2 risky regexes · 1 exponential · 1 polynomial · 14 safe · 0 skipped · 16 total

It reads regex literals and new RegExp("…") strings out of your .js/.ts (and jsx/tsx/mjs/cjs), tells regexes from division, and never flags a safe one if it can help it — false positives are how a security tool gets ignored.

Install

npx will-it-redos scan .      # no install
npm i -g will-it-redos        # keep it; the bin is also `redos`

Node ≥ 18. Zero-dependency core (the CLI adds cac + picocolors). No API key, no network, no telemetry — it runs entirely on your machine, because it's literally just running regexes against strings really fast.

Use it as a CI gate

scan exits non-zero when it finds something, so one line keeps catastrophic regexes out of your codebase forever:

# .github/workflows/ci.yml
- run: npx will-it-redos scan src
// package.json
{ "scripts": { "lint:redos": "will-it-redos scan src --min-severity polynomial" } }

Exit 0 = clean · 1 = a vulnerable regex was found · 2 = usage error.

What it catches

| Shape | Example | Verdict | | ----- | ------- | ------- | | Nested quantifier | (a+)+, (a*)*, ([a-z]+)*, (.*)* | exponential | | Quantified ambiguous group | (\w+\s?)*, ([^=]+)+= | exponential | | Overlapping alternation under a loop | (a\|a)*, (\w\|\d)*, (.\|a)* | exponential | | Adjacent greedy quantifiers | .*.*=.*, \s*\s*$, \d+\d+ | polynomial |

It models JS regex syntax (classes, groups, alternation, quantifiers, lookarounds, backrefs) and reasons about character-set overlap and empty-matchability — the two properties that make backtracking blow up. Anything it can't parse is reported as skipped, never guessed.

Honest about the limits

ReDoS detection is undecidable in general, so will-it-redos aims for high recall on the real-world canon with near-zero false positives:

  • It may miss exotic constructions (bounded-repeat amplification like (.*a){200}, backreference-driven blowup). --prove is the backstop: if it flagged something, the timing shows you it's real.
  • It does not execute your code — it reads source text and analyzes patterns.
  • The --prove timing is bounded and self-protecting (small steps, hard caps), so the tool itself can never hang.

Library API

The analyzer is pure and browser-safe:

import { analyzePattern } from "will-it-redos";

const r = analyzePattern("(a+)+$");
r.status;                       // "exponential"
r.findings[0].attack.build(50000);   // the evil input, ready to fire

Roadmap

  • 🌐 Web playground — paste a regex, watch it melt (100% client-side; the engine already runs in a browser).
  • Bounded-repeat amplification ((.*a){n}) and backreference analysis.
  • Auto-fix suggestions (atomic groups / possessive rewrites / anchoring).
  • ESLint plugin and a --git-diff mode for pre-commit.

💖 Sponsor

Free, MIT, built in spare time. If it caught a regex before it caught you:

  • Star the repo — so the next person finds it before the incident.
  • 🍋 Sponsor via Lemon Squeezy — one-time or recurring.

License

MIT © will-it-redos contributors