mediumCVSS 5.3Vulnerability

CVE-2026-85999

## Summary Before tokenizing, `selector_iter` trims leading/trailing whitespace and comments by running two regexes over the whole raw selector with `.search()`. The trailing one, `RE_WS_END = re.compile(r'{WSC}*$')`, is anchored only at the end (`$`), not the start. Because `.search()` retries the pattern at every offset, a long run of whitespace or CSS comments that is not sitting exactly at the end of the string makes each retry greedily consume the run and then fail `$`, producing O(n²) time. This triggers on perfectly valid selectors — e.g. a descendant combinator with a long whitespace gap, `a` + `" "*n` + `b` — so no malformed input is required. A single valid ~20 KB selector stalls the interpreter for ~10 s of CPU. ## Trust model (Q0) The selector string is the input, reaching this code via `soupsieve.compile()`, the `soupsieve.select/iselect/match/filter` helpers, and BeautifulSoup's `soup.select(selector)` / `soup.select_one(selector)`. Exploitable wherever an application passes a user-controlled CSS selector to BeautifulSoup/soupsieve. Applications using only hard-coded selectors are unaffected. ## Root cause (exact anchors) — `src/soupsieve/css_parser.py` ```python # line 185-186 RE_WS_BEGIN = re.compile(fr'^{WSC}*') # anchored at start -> .search() only tries pos 0 -> linear (safe) RE_WS_END = re.compile(fr'{WSC}*$') # NOT anchored at start -> .search() tries every offset # selector_iter, lines ~1322-1326 m = RE_WS_BEGIN.search(pattern) index = m.end(0) if m else 0 m = RE_WS_END.search(pattern) # <-- O(n^2) here end = (m.start(0) - 1) if m else (len(pattern) - 1) ``` `WSC = (?:{WS}|{COMMENTS})`. For `RE_WS_END = (?:WS|COMMENTS)*$`, `.search()` walks start offsets 0..n. Whenever the offset lands inside a long whitespace/comment run, `(?:WS|COMMENTS)*` greedily consumes to the run's end, then `$` fails (a non-whitespace char follows), the engine backtracks the whole run, the offset advances by one, and the work repeats — O

Properties

ghsa_id
GHSA-j934-xhv5-fg8f
severity
medium
summary
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
cvss_score
5.3
cve_id
CVE-2026-85999
cvss_vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L
signal_observed_at
2026-09-17T21:32:39+00:00
is_ghsa_only
false
ghsa_published
2026-09-17T20:32:53Z
source_url
https://github.com/advisories/GHSA-j934-xhv5-fg8f
ghsa_updated
2026-09-17T20:32:55Z

Related Entities (5)

VULNERABLE_TO (1)

[Software]pip/soupsieve

AFFECTS (1)

[Software]pip/soupsieve

HAS_WEAKNESS (2)

[Weakness]Inefficient Regular Expression Complexity
[Weakness]Uncontrolled Resource Consumption

REPORTED_BY (1)

[Source]GitHub Advisory Database

Explore deeper with Ninja Signal's threat intelligence graph

CVE-2026-85999 (CVSS 5.3) — Ninja Signal Threat Intelligence | Ninja Signal