CVE-2026-49477 Overview
CVE-2026-49477 is a denial-of-service vulnerability in Soup Sieve, the CSS selector library used by Beautiful Soup 4 for querying parsed HTML and XML documents. The CSS selector parser in soupsieve/css_parser.py contains a regular expression vulnerable to catastrophic backtracking when handling an attribute selector with an unterminated quoted value. An attacker who can supply untrusted CSS selector strings to soupsieve.compile() or to Beautiful Soup's .select() and .select_one() methods can trigger CPU exhaustion. The issue is fixed in Soup Sieve 2.8.4.
Critical Impact
Applications that pass user-controlled CSS selectors to Beautiful Soup or Soup Sieve can be forced into CPU-bound processing, causing service unavailability with a single crafted selector string.
Affected Products
- Soup Sieve versions prior to 2.8.4
- Beautiful Soup 4 deployments that expose selector strings to untrusted input
- Python applications embedding Soup Sieve as a scraping or parsing dependency
Discovery Timeline
- 2026-07-14 - CVE-2026-49477 published to the National Vulnerability Database
- 2026-07-15 - Last updated in NVD database
Technical Details for CVE-2026-49477
Vulnerability Analysis
Soup Sieve compiles CSS selector strings into an internal representation before matching them against a parsed document tree. The parser in soupsieve/css_parser.py relies on regular expressions to tokenize selector components, including attribute selectors of the form [attr="value"]. One of these expressions exhibits catastrophic backtracking behavior [CWE-400] when the quoted value portion of an attribute selector is left unterminated.
When the regex engine encounters such malformed input, it explores an exponential number of matching paths before failing. Processing time scales non-linearly with input length, allowing short crafted strings to consume seconds or minutes of CPU time. In a web service or scraping pipeline, a handful of concurrent requests can saturate available cores and prevent legitimate work from completing.
Root Cause
The root cause is an ambiguous regular expression used to parse quoted attribute values. The pattern permits multiple ways to match the same input when the closing quote is absent, forcing the engine into a backtracking loop. This is a classic Regular Expression Denial of Service (ReDoS) pattern that surfaces only when the parser receives adversarial input outside its expected grammar.
Attack Vector
Exploitation requires only the ability to supply a CSS selector string to a vulnerable code path. Common exposure points include search or filter parameters in web scrapers, template engines that accept selector expressions, HTML sanitizers configured through user input, and any REST API that forwards client-supplied selectors to Beautiful Soup's .select() or .select_one() methods. No authentication or user interaction is required when the selector input is reachable over the network.
# Patch reference - version bump in soupsieve/__meta__.py
return Version(major, minor, micro, release, pre, post, dev)
-__version_info__ = Version(2, 8, 3, "final")
+__version_info__ = Version(2, 8, 4, "final")
__version__ = __version_info__._get_canonical()
Source: GitHub Commit eb43976
Detection Methods for CVE-2026-49477
Indicators of Compromise
- Python worker processes sustaining 100% CPU while handling requests that include CSS selector inputs.
- Application logs showing timeouts or thread stalls originating in soupsieve/css_parser.py.
- HTTP request payloads containing attribute selectors with unmatched quote characters, such as [attr="value.
- Sudden growth in request latency percentiles for endpoints that invoke Beautiful Soup selection APIs.
Detection Strategies
- Inventory Python dependencies and flag any project pinning soupsieve below version 2.8.4.
- Add runtime timeouts around soupsieve.compile() and Beautiful Soup .select() calls, then log timeout events for triage.
- Perform static analysis on application code to identify paths where untrusted input reaches selector parameters.
- Deploy web application firewall rules that inspect query parameters and JSON fields for malformed CSS selector patterns.
Monitoring Recommendations
- Track per-request CPU time on services that parse or scrape HTML, alerting on outliers that exceed baseline execution windows.
- Monitor Python process thread dumps for stack frames inside css_parser.py during high-load events.
- Correlate elevated CPU usage with request identifiers to isolate the specific selector payloads triggering slowdowns.
How to Mitigate CVE-2026-49477
Immediate Actions Required
- Upgrade Soup Sieve to version 2.8.4 or later across all Python environments and container images.
- Rebuild and redeploy any application bundling Beautiful Soup 4 to pull in the fixed transitive dependency.
- Validate or reject CSS selector inputs from untrusted sources before passing them to soupsieve.compile() or .select().
- Apply request-level CPU and wall-clock timeouts to endpoints that invoke HTML parsing on user input.
Patch Information
The fix is included in Soup Sieve 2.8.4. Review the GitHub Security Advisory GHSA-836r-79rf-4m37 for maintainer guidance and the GitHub Release 2.8.4 notes for the corrected parser implementation.
Workarounds
- Reject selector strings that contain unbalanced quote characters before invoking the parser.
- Enforce a maximum length on user-supplied selector strings to bound worst-case parsing time.
- Execute selector parsing in a subprocess or worker with a strict CPU quota so a single request cannot exhaust the host.
- Where feasible, restrict user input to a fixed set of predefined selectors rather than allowing arbitrary CSS expressions.
# Upgrade soupsieve to the patched release
pip install --upgrade "soupsieve>=2.8.4"
# Verify the installed version
python -c "import soupsieve; print(soupsieve.__version__)"
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

