CVE-2026-85999
Quadratic CPU DoS via long whitespace/comments in Soup Sieve parsing
- CVSS 5.3
- 400
- Resource Management
- Remote
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.
- CWE
- 400
- CVSS base score
- 5.3
- Published
- 2026-09-17
- OWASP
- A06 Vulnerable and Outdated Components
- Orthogonal defect classification
- Algorithm
- Code defect classification
- Incorrect Algorithm
- Category
- Resource Management
- Subcategory
- Resource Exhaustion
- Accessibility scope
- Remote
- Impact
- Denial of Service (DoS)
- Affected component
- Soup Sieve
- Fixed by upgrading
- Yes
Solution
Upgrade Soup Sieve to version 2.9 or later.
Vulnerable code sample
import soupsieve
from bs4 import BeautifulSoup
def find_links(html, selector):
soup = BeautifulSoup(html, "html.parser")
# VULNERABLE: directly compiling user-controlled selector triggers quadratic regex in soupsieve
compiled = soupsieve.compile(selector)
return [tag.get('href') for tag in soup.select(compiled)]Patched code sample
import re
import soupsieve
from bs4 import BeautifulSoup
def find_links(html, selector):
soup = BeautifulSoup(html, "html.parser")
# FIX: collapse whitespace to prevent quadratic regex in soupsieve
safe_selector = re.sub(r'\s+', ' ', selector)
compiled = soupsieve.compile(safe_selector)
return [tag.get('href') for tag in soup.select(compiled)]Payload
__VAITP_MODEL_REFUSED__
Cite this entry
@misc{vaitp:cve202685999,
title = {{Quadratic CPU DoS via long whitespace/comments in Soup Sieve parsing}},
author = {Bogaerts, Fr\'ed\'eric and Ivaki, Naghmeh and Fonseca, Jos\'e},
year = {2026},
note = {VAITP Python Vulnerability Dataset, entry CVE-2026-85999},
howpublished = {\url{https://netpack.pt/vaitp/vulnerability/CVE-2026-85999/}}
}
Introducing the "VAITP dataset": a specialized repository of Python vulnerabilities and patches, meticulously compiled for the use of the security research community. As Python's prominence grows, understanding and addressing potential security vulnerabilities become crucial. Crafted by and for the cybersecurity community, this dataset offers a valuable resource for researchers, analysts, and developers to analyze and mitigate the security risks associated with Python. Through the comprehensive exploration of vulnerabilities and corresponding patches, the VAITP dataset fosters a safer and more resilient Python ecosystem, encouraging collaborative advancements in programming security.
The supreme art of war is to subdue the enemy without fighting.
Sun Tzu – “The Art of War”
:: Shaping the future through research and ingenuity ::
