Inefficient Regular Expression Complexity vulnerability in the CSS scrubber in rrrene html_sanitize_ex allows an unauthenticated remote attacker to exhaust server CPU via a long CSS declaration in sanitized HTML. The declaration regex in HtmlSanitizeEx.Scrubber.CSS.scrub/1 matches the property name with an unbounded greedy [-\w]+ followed by a mandatory :, so a long run of word characters not followed by a colon makes the engine give back one character at a time and retry the colon at every start offset. The work is quadratic in the length of the run, and no length cap is applied to the CSS handed to the scrubber. An 80 KB <style> body costs roughly 2.4 seconds of scheduler time, so a few concurrent requests saturate the BEAM scheduler pool and make the application unresponsive.
The impact is CPU exhaustion only. Nothing is read, modified or disclosed.
This issue affects html_sanitize_ex: from 0.3.1 before 1.4.5 and from 1.5.0-rc.0 before 1.5.3.
In OpenStack Swift through 2.38.0, the proxy server Accept header parser contains a regular expression vulnerable to catastrophic backtracking (ReDoS). The "qdtext" pattern (?:[^"]|\\.)* allows an unauthenticated remote attacker to send a crafted Accept header that causes exponential CPU consumption in the proxy worker. A payload of 32 backslash-character pairs exceeds 30 seconds of CPU time. No authentication is required. Repeated requests can exhaust all proxy worker threads, resulting in a complete denial of service.
A Regular Expression Denial of Service (ReDoS) vulnerability exists in Apache Superset versions 1.5.0 through 5.0.0. The vulnerability is located in the sql_parse.py component, specifically within the SQL_REGEX used for parsing SQL statements in the sqlparse library integration.
The affected regular expression contains overlapping disjunctions that share a common outer quantifier. An authenticated attacker can exploit this by sending a maliciously crafted input string (specifically a long sequence of backslashes or similar characters) to endpoints that process SQL queries
This issue affects Apache Superset: before 6.0.0.
Users are recommended to upgrade to version 6.0.0, which fixes the issue.
Workarounds:
● WAF Rules: Implement Web Application Firewall (WAF) rules to detect and block
requests containing excessively long sequences of backslashes or suspicious repeated
patterns in the queries.extras.where parameter.
● Rate Limiting: Ensure strict rate limiting is applied to the /api/v1/chart/data endpoint to
reduce the impact of potential attacks.
Date::Manip versions through 7.00 for Perl allow CPU exhaustion via quadratic backtracking in the unanchored time substitution in _parse_time.
_parse_time removes a time from anywhere in the string with the unanchored substitution `s/$timerx/ /`, where $timerx is an auto-generated alternation of time patterns reached through a leading `(?:$atrx|^|\s+)`. The engine therefore retries the match at every position of an interior whitespace run: at each start position the leading `\s+` consumes the rest of the run greedily, the time alternation fails because the run holds no digits, and the engine backtracks a space at a time across the run before advancing the start position, which is quadratic in the length of the run. No time need be present in the string for this to happen, only a long run of whitespace, and the parse time rises about fourfold for each doubling of the run: a few kilobytes of whitespace costs seconds of CPU per parse and tens of kilobytes costs minutes.
Any caller that passes an untrusted string of unbounded length to ParseDate(), Date::Manip::Date->parse() or ->parse_time() can be made to spend unbounded CPU in a single parse, a denial of service.
A vulnerability in HAPI FHIR's org.hl7.fhir.core module allows denial of service via inefficient regular expression evaluation. Versions prior to 6.9.4.2 and between 6.9.5 and before 6.9.9 accept arbitrary FHIRPath expressions without sufficient input validation. The matches(), matchesFull(), and replaceMatches() functions pass user-controlled regex patterns to Java's Pattern.compile() and String.replaceAll() with an incomplete timeout mechanism, enabling catastrophic backtracking and CPU exhaustion. This issue is fixed in versions 6.9.9 and 6.9.4.2.
CVE-2026-52746 is a vulnerability in jsonata-js's JSONata library affecting versions prior to 2.2.0 and 1.8.9. It involves inefficient regular expression complexity in the $toMillis function's ISO-8601 validation regex. Malicious non-matching inputs can trigger superlinear backtracking, causing denial of service. The issue is fixed in versions 2.2.0 and 1.8.9.
HTTP::Date versions before 6.08 for Perl allow CPU exhaustion via polynomial regex backtracking in parse_date.
parse_date() matches the date string against a chain of alternative regexes, and str2time() delegates to it. Several of these patterns place unbounded quantifiers next to each other before a trailing `\s*$` anchor. A valid date prefix followed by a long interior run of digits, letters, or whitespace and a single trailing byte that defeats the final match forces the engine to repartition the run, giving polynomial (about quadratic) backtracking. A header value of a few tens of kilobytes runs for tens of seconds of CPU.
HTTP::Date parses timestamps such as HTTP `Date`, `Expires`, and `Last-Modified` headers, which commonly originate from untrusted sources. Any caller that passes an untrusted date header to str2time() or parse_date() can be driven to consume unbounded CPU, a denial of service.
Grav before 2.0.4 contains a regular expression denial of service (ReDoS) vulnerability in the regex_replace filter and function, which are allowlisted in the Twig content sandbox. When Twig processing in page content is enabled (security.twig_content.process_enabled: true, disabled by default), an authenticated page editor can supply a catastrophically backtracking PCRE pattern that is passed directly to PHP's preg_replace(), causing unbounded CPU consumption and denial of service to the web server process.
HAPI FHIR is a complete implementation of the HL7 FHIR standard for healthcare interoperability in Java. Prior to 6.9.7, the FHIRPathEngine implementation passes user-controlled regular expressions from matches(), matchesFull(), and replaceMatches() to Java regex operations without effective timeouts, allowing catastrophic backtracking and denial of service. This issue is fixed in version 6.9.7.
### Summary
The CSS selector parser in soupsieve (the CSS selector engine for Beautiful Soup 4) contains a regular expression vulnerable to catastrophic backtracking. When processing an attribute selector with an unterminated quoted value, the `VALUE` regex pattern in `css_parser.py` enters exponential backtracking. A payload of only **300 bytes** causes the regex engine to hang for **over 3 seconds**, enabling a trivial Regular Expression Denial of Service (ReDoS) attack.
To be completely transparent, AI tools helped surface this issue. However, this was independently reproduced and carefully validated.
Any application that passes untrusted CSS selector strings to `soupsieve.compile()` or Beautiful Soup's `.select()` / `.select_one()` is affected.
### Details
**Affected code:** `soupsieve/css_parser.py`, line ~121 - `RE_VALUES` / `VALUE` regex pattern
The soupsieve CSS parser uses a compiled regular expression to tokenise attribute selector values. This pattern matches both quoted strings (`"value"` or `'value'`) and unquoted identifiers. The regex contains alternation branches for:
1. Double-quoted strings: `"[^"\\]*(?:\\.[^"\\]*)*"`
2. Single-quoted strings: `'[^'\\]*(?:\\.[^'\\]*)*'`
3. Unquoted identifiers
When an attribute selector contains an **unterminated quoted value** - e.g., `[a="xxxx...` (opening `"` but no closing `"`) -” the regex engine attempts to match the quoted-string branch. After that branch fails (no closing quote), the engine backtracks and attempts to match the remaining input against subsequent alternation branches and parent patterns. The structure of the pattern causes **catastrophic backtracking** where the number of backtracking steps grows exponentially with the length of the content between the opening quote and the end of the string.
**Root cause:** The regex pattern does not anchor or guard against the case where a quoted string is never terminated. The overlapping character classes across alternation branches create exponential backtracking when the quoted-string branch fails on long input.
**Key characteristics:**
- **Input size:** Only 300 bytes are needed to trigger a >3 second hang
- **Amplification:** Each additional character approximately doubles the backtracking time
- **No memory impact:** The attack consumes CPU only (regex backtracking is compute-bound)
### Proof of Concept
```python
import time
import soupsieve as sv
PAYLOAD_LEN = 300
# Control: well-formed selector with terminated quote (completes instantly)
well_formed = '[a="' + ('x' * PAYLOAD_LEN) + '"]'
start = time.perf_counter()
try:
sv.compile(well_formed)
except Exception:
pass
control_time = time.perf_counter() - start
print(f"Well-formed selector ({len(well_formed)} bytes): {control_time:.4f}s")
# Exploit: unterminated quote triggers catastrophic regex backtracking
malformed = '[a="' + ('x' * PAYLOAD_LEN)
start = time.perf_counter()
try:
sv.compile(malformed) # WARNING: This will hang for >3 seconds
except Exception:
pass
exploit_time = time.perf_counter() - start
print(f"Malformed selector ({len(malformed)} bytes): {exploit_time:.4f}s")
slowdown = exploit_time / max(control_time, 1e-9)
print(f"Slowdown: {slowdown:.0f}x")
# Expected output:
# Well-formed selector (306 bytes): ~0.001s
# Malformed selector (304 bytes): >3.0s (may need to be killed)
# Slowdown: >3000x
#
# NOTE: On some systems the malformed selector may hang indefinitely.
# Use a timeout mechanism (signal.alarm, threading.Timer) when testing.
```
**Safe testing variant with timeout:**
```python
import signal
import soupsieve as sv
def timeout_handler(signum, frame):
raise TimeoutError("ReDoS confirmed: regex backtracking exceeded timeout")
PAYLOAD_LEN = 300
malformed = '[a="' + ('x' * PAYLOAD_LEN)
signal.signal(signal.SIGALRM, timeout_handler)
signal.alarm(3) # 3-second timeout
try:
sv.compile(malformed)
print("Selector compiled (not vulnerable)")
except TimeoutError as e:
print(f"VULNERABLE: {e}")
except Exception as e:
print(f"Other error: {e}")
finally:
signal.alarm(0) # Cancel the alarm
```
### Impact
**Severity: High**
An attacker can cause CPU exhaustion on any server-side Python application that compiles user-supplied CSS selectors via soupsieve. The attack is particularly dangerous because:
1. **Tiny payload:** Only 300 bytes are needed - well within typical URL parameter, form field, or API request limits
2. **No special characters:** The payload consists entirely of printable ASCII characters (`[a="xxx...`)
3. **Exponential scaling:** Each additional byte approximately doubles the backtracking time, making the attack easily tuneable
4. **Thread blocking:** The regex engine blocks the calling thread with no opportunity for interruption (except via OS signals)
| Parameter | Value |
|---|---|
| Input size | 300 bytes |
| CPU time consumed | >3 seconds (exponential with payload length) |
| Memory consumed | Negligible (CPU-only attack) |
| Authentication requir
The Node.js package markdown-it, specifically its linkify-it component prior to version 5.0.1, contains an algorithmic complexity vulnerability in the LinkifyIt.prototype.match function. This function exhibits O(N²) complexity when processing inputs with many fuzzy links or emails due to repeated rescanning of progressively shorter input tails. This can lead to denial of service (DoS) conditions if untrusted Markdown with linkify enabled is synchronously rendered on a request hot path. The issue is resolved in version 5.0.1.
UAParser.js is a JavaScript library to detect browsers, operating systems, CPUs, and devices from user-agent data. From 2.0.1 until 2.0.10, a regular expression denial-of-service vulnerability exists when using the Client Hints API. By sending a crafted Sec-CH-UA-Model header to an application that calls UAParser(headers).withClientHints(), an attacker can cause excessive CPU time due to catastrophic backtracking in the device regex because Client Hints values are copied without the UA_MAX_LENGTH limit used for User-Agent values. This issue is fixed in version 2.0.10.
Phalcon is a high-performance, full-stack PHP framework. Prior to 5.15.0, every Phalcon MVC application built with a default router registers a built-in route whose compiled PCRE pattern contains the nested quantifier (/.), and the same construct is produced by the /:params placeholder and the CLI router. Phalcon\Mvc\Router::handle() matches this pattern against the attacker-controlled request URI on every request, so a crafted path such as one containing repeated slashes followed by decoded newlines can trigger catastrophic backtracking and cause CPU exhaustion or route-matching failure. This issue is fixed in version 5.15.0.
A Regular Expression Denial of Service (ReDoS) vulnerability (CVE-2026-15154) exists in the guardrails-detectors component of Red Hat OpenShift AI. This vulnerability allows remote attackers to send specially crafted regular expressions to the public detection API, causing catastrophic backtracking and resulting in a worker process consuming 100% CPU indefinitely. This leads to denial of service for the guardrails-mediated large language model pipeline. The issue affects specific versions of Red Hat OpenShift AI and has been assigned a medium severity rating with a CVSS score of 6.5. Red Hat has released updated images and version 2.25.10 to address this vulnerability.
HAPI FHIR is a complete implementation of the HL7 FHIR standard for healthcare interoperability in Java. Prior to 6.9.10, the fix for CVE-2026-45367 incompletely patched the DSTU2 module, leaving FHIRPathEngine.matches() in org.hl7.fhir.dstu2/utils/FHIRPathEngine.java to call raw String.matches(sw) without RegexTimeout protection while replaceMatches() was updated, allowing an unauthenticated attacker to trigger catastrophic regex backtracking and exhaust server CPU. This issue is fixed in version 6.9.10.
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a Markdown document containing many repeated or distinct reference-link definitions causes quadratic work in src/mistune/block_parser.py and the ref_links environment dictionary handling, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, long sequences of well-formed double-asterisk or triple-asterisk emphasis pairs around a character cause quadratic work in src/mistune/inline_parser.py because the parser scans forward for matching close markers from every potential opening run, allowing denial of service in default Mistune parsing. This issue is fixed in version 3.3.0.
Mistune is a Python Markdown parser with renderers and plugins. Prior to 3.3.0, a run of closed tilde, equals-sign, or caret marker pairs around a character causes quadratic work in src/mistune/plugins/formatting.py when the strikethrough, mark, or insert plugin scans for matching markers from each possible start position, allowing denial of service through CPU exhaustion. This issue is fixed in version 3.3.0.
String::Util versions before 1.36 for Perl are susceptible to a regular expression denial of service.
The trim and rtrim functions stripped trailing whitespace with s/\s*$//u. Because \s* matches greedily and the $ anchor fails whenever a non-whitespace character follows the whitespace, the regex engine retries the match at each offset of a long whitespace run, producing quadratic backtracking. The fix replaces \s*$ with \s+$.
Any caller that passes untrusted input to trim or rtrim can trigger CPU exhaustion with a string containing a long run of whitespace.
vLLM is a high-throughput and memory-efficient inference and serving engine for LLMs. Prior to 0.24.0, the structured_outputs.regex API parameter passes a user-supplied regular expression string directly to the grammar compiler backends with no compilation timeout; in the xgrammar backend the string reaches the regex compiler with no guard, and in the outlines backend the validation step blocks structural issues such as lookarounds and backreferences but performs no complexity analysis, so a pattern with nested quantifiers passes all checks and causes exponential state-space expansion, allowing a single request containing an adversarial regex to hang an inference worker indefinitely and deny service. This issue is fixed in version 0.24.0.