← THE WIRE
CODE May 15, 2026 · 5 min read

ReDoS keeps making the CVE list — six 2026 vulnerabilities that came from one bad regex each

Regular expressions are one of the most surprising security risks in modern software. The class of vulnerability called ReDoS — Regular expression Denial of Service — happens when a regex pattern has exponential or super-linear worst-case complexity on certain inputs, and an attacker can craft an input that pegs CPU for seconds or minutes. It's not a theoretical risk. Six CVEs in the first half of 2026 came down to exactly this, in projects ranging from validation libraries to log parsers to email-address verifiers. The patterns are always the same shape. The fix is also always the same shape.

Regex Complexity Scorer
Score regex patterns for ReDoS and backtracking risk
UDT
UDT News Desk
Industry Analysis

The three patterns that produce ReDoS

Almost every ReDoS vulnerability comes from one of three shapes. Nested quantifiers: (a+)+ or (a*)*. The inner quantifier can match the same characters multiple ways, and the outer quantifier multiplies the ambiguity. On an input of aaaaaaaaaab, the engine tries every way to split the a's between the inner and outer repeats before concluding there's no match. Time complexity: exponential in input length.

Alternation inside a repeat: (a|aa)+. The two alternatives overlap — an aa can be matched as one aa or two a's. The repeat then explores both interpretations across every position. Same pathology, different surface.

Optional sub-patterns inside a repeat: (a?){n}a{n} or anything that lets the engine backtrack through optional matches inside a counted or unbounded repeat. A famous 2019 Cloudflare outage was caused by a regex of this shape in a WAF rule. The 2026 CVEs include three variants of it in different validation libraries.

Six 2026 CVEs, one pattern each

CVE-2026-1247 in a Node.js URL parser: a regex of the form ^(\w+)+:\/\/(.+)$. The (\w+)+ is the classic nested quantifier. Crafted URL inputs caused 10-second event-loop stalls on the affected version.

CVE-2026-3411 in a Python email validator: ^([^@\s]+|".+")+@.+$ — alternation inside a repeat. The fix shipped two weeks after disclosure replaced the regex with a hand-written parser.

CVE-2026-4889 in a Java log parser: (\d+\.)+\d+ for parsing version strings. Worked fine until someone hit it with a multi-thousand-character version string designed to maximize backtracking.

CVE-2026-5912, CVE-2026-6034, and CVE-2026-6190 all share the same shape: a credit-card validator, a phone-number validator, and a query-string parser, each with a different flavor of .* followed by an optional or alternating group followed by an anchor. The same pattern, six times.

Why this keeps happening

ReDoS keeps shipping because catastrophic backtracking is invisible until you hit it. The regex compiles. The pattern matches the test cases. Static analysis tools mostly don't flag it, because the worst-case complexity depends on input characteristics that are hard to enumerate. Code review catches it if the reviewer knows the patterns, but most reviewers don't think in worst-case regex complexity terms. So the bad regex ships, sits in production for years, and only surfaces when an attacker (or a clumsy user) hits the input that triggers the exponential blowup.

There are two real defenses. First, prefer non-regex parsers for structured input — a hand-written URL or email parser is more code but has guaranteed linear complexity and is easier to reason about. Second, when regex is the right tool, score the pattern for ReDoS risk before shipping it. Nested quantifiers are a smell. Alternation inside a repeat is a smell. Lookaround inside a repeat is a smell. Catching them at code-review time costs minutes; catching them in a post-mortem costs days.

What we'd actually do

If you maintain a codebase that accepts regex patterns from users, or that uses regex extensively against user input, the cheapest defense is automated complexity scoring on every pattern before it ships. There are decent linters for this in most languages — ESLint's no-control-regex and redos plugins, Python's re2 as a drop-in replacement that refuses to compile catastrophic patterns, Go's regexp package which uses RE2 internally and is immune to ReDoS by design.

For one-off pattern checks during code review or pull-request review, a visual scorer that flags the same five or six classic patterns is fast and good enough. Drop the pattern in, see the tier, ship or refactor. The cost of doing this is seconds; the cost of not doing it shows up as your project's CVE number in a security advisory feed.

CONTEXT Code · UDT News Desk May 15, 2026
UDT
UDT News Desk
The UDT News Desk covers what's moving in design, frontend, and the tools designers and developers use. Edited and curated by the team at Ultimate Design Tools.