safe-regex
Detects regular expressions prone to catastrophic backtracking (ReDoS) using AST-based star-height analysis.
Repository Health
Technical Analysis
safe-regex is a small, focused npm library that checks whether a regular expression is safe from catastrophic (exponential-time) backtracking before it ever runs against untrusted input. Rather than pattern-matching against a blocklist of “known bad” regex shapes, it parses the target regex into an AST with the regexp-tree package and measures its structural “star height” — how deeply repetition operators (*, +, {n,m}) are nested inside one another — flagging anything with a star height greater than one, or with more repetition operators than a configurable limit (25 by default).
The library exposes a single function, safeRegex(re, opts), that accepts either a RegExp object or a string and returns a boolean. Internally it delegates to a small family of pluggable Analyzer subclasses (currently just one, HeuristicAnalyzer) so additional detection strategies can be added later without changing the public API. A companion CLI (bin/cli.js) wraps the same check for batch analysis of JSON-described patterns, but the primary integration path is require('safe-regex') inside application code — for example, rejecting user-supplied search patterns before compiling them into a live RegExp.
The README is unusually candid about the tool’s limits: it documents specific known false positives (linear-time regexes it still flags, like (ab*)+) and false negatives (disjunction-driven blowups it misses, like (a|a)*), and points users toward the author’s related vuln-regex-detector project for more rigorous analysis. That transparency, plus a Jest test suite enforcing 100% coverage across a wide range of regex syntax, makes it a well-scoped first line of defense against ReDoS rather than a complete solution.
What You Get
- A single
safeRegex(re, opts)function that returnstrue/falsefor whether aRegExpor regex string is safe from catastrophic backtracking - AST-based star-height analysis via
regexp-tree, instead of a brittle blocklist of known-bad patterns - A configurable
opts.limitfor the maximum number of repetition operators allowed (default 25) - Fail-safe behavior — invalid, unparseable, or non-regex input is treated as unsafe rather than throwing
- A
bin/cli.jscommand-line tool for batch-checking JSON-described patterns outside of application code - A documented, extensible
Analyzerbase class so additional detection heuristics can be added without changing the public API
Common Use Cases
- Validating user-supplied search or filter patterns before compiling them into a live
RegExpin a web app - Screening regex patterns accepted from configuration files, admin panels, or plugin systems where the source isn’t fully trusted
- Adding an automated guard in CI or a linter step that rejects newly introduced regexes with dangerous nesting
- Batch-auditing an existing codebase’s regex literals for catastrophic-backtracking risk via the CLI
Under The Hood
Architecture
The library is a thin, layered design: index.js exposes the single public entry point safeRegex(re, opts), which builds an Args object (the parsed RegExp plus AnalyzerOptions) and hands it to every analyzer registered in analyzer-family.js — currently just HeuristicAnalyzer — OR-ing their isVulnerable() results together so any single analyzer flagging a pattern is enough to mark it unsafe. Each analyzer extends the abstract Analyzer base class defined in analyzer.js (isVulnerable() / genAttackString()), so new detection strategies can be added to the analyzerFamily array without touching index.js or the public API. bin/cli.js is a separate, thin wrapper around the same safeRegex call for batch JSON-file processing — it is not part of the core execution path.
Tech Stack
Plain JavaScript with no runtime framework. The sole functional dependency is regexp-tree, used to parse a RegExp into an AST and traverse its Repetition nodes to compute nesting depth (star height) and total repetition count. The package is authored in src/ and built to dist/ (the published main entry) via Babel (@babel/cli, @babel/core, @babel/preset-env). Tests run under Jest. CI is configured through both a legacy .travis.yml and a GitHub Actions workflow (.github/workflows/npm-publish.yml) for publishing. There is no database, network I/O, or async code anywhere in the library — it is a pure, synchronous computation over a parsed AST.
Code Quality
The Jest suite in src/test/regex.spec.js is thorough for the library’s scope: it exercises the full range of JS regex syntax (lookaround, named groups, backreferences), confirms linear- and polynomial-time patterns are accepted, confirms known exponential-time (nested-star) patterns are rejected, and explicitly documents — via inline TODO comments and dedicated test blocks — the analyzer’s known false positives and false negatives rather than hiding them. Coverage thresholds in package.json are set to 100% across statements, branches, functions, and lines. Error handling favors fail-safe defaults: invalid or unparseable regexes are caught and treated as unsafe rather than allowed to throw. There is no TypeScript and no linter configuration present in the repo, so type safety and style enforcement rely entirely on test coverage and code review.
API Design
The public surface is deliberately minimal — one function, one options object, one boolean return value — which keeps integration nearly frictionless (if (!safeRegex(pattern)) reject()). The library’s specific technical choice is measuring structural “star height” from a parsed AST rather than matching against a list of known-dangerous regex shapes, a narrower but more principled heuristic than many naive ReDoS scanners use. It does not attempt full NFA state-space analysis (the author’s related vuln-regex-detector project targets that), and the README is explicit about the resulting blind spots, which is unusually honest developer-experience documentation for a security-adjacent utility.
Used by 4 apps in this directory
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.
oh-my-claudecode
AI Agents
Multi-agent orchestration for Claude Code with zero learning curve — install as a plugin or npm CLI and coordinate parallel Claude Code agents through pre-built workflows instead of managing them by hand.
OmniRoute
AI Agents
A free, open-source AI gateway connecting Claude Code, Codex, Cursor, Cline, and Copilot to 237 AI providers (90+ free) through one endpoint, with automatic fallback and token-compression to stretch free-tier limits further.
Wiki.js
Knowledge Management · Collaboration
A modern, self-hosted wiki platform built on Node.js with a rich plugin ecosystem for authentication, search, storage, and rendering that adapts to any team's infrastructure.