CVE-2026-126190: Soup Sieve flaw hits Beautiful Soup apps

A flaw in Soup Sieve, the CSS selector library built into Beautiful Soup 4, lets a remote attacker stall a Python application with a document of about one kilobyte. Tracked as CVE-2026-126190, the vulnerability was published on 13 November 2026 and carries a CVSS score of 7.5. It is fixed in Soup Sieve 4.0.
Soup Sieve is the default CSS selector engine for Beautiful Soup 4, one of the most widely used Python libraries for parsing HTML and XML. Any application that runs CSS selectors against markup supplied by untrusted users, directly or through Beautiful Soup's select() or select_one() methods, may be affected.
How a 1 KB document can stall an application
The flaw is an inefficient algorithmic complexity vulnerability, classified as CWE-407. Matching a selector that uses the descendant combinator, such as "section div div", takes time that grows polynomially with how deeply the document is nested. Each extra descendant combinator raises the degree by one, so a selector with k descendant combinators takes O(n^(k+1)) time on a chain of n nested elements.
The cause is that Soup Sieve checked each element against part of the selector and then walked up through its ancestors looking for a match, retrying the rest of the selector from each ancestor without reusing any earlier work. The worst case comes when the leftmost part of the selector never matches, so every walk runs all the way to the root of the document and no search can stop early.
The advisory's benchmarks show how severe the slowdown is. On Soup Sieve 3.0.4, a 2 KB document of 800 nested div tags took 53 seconds to match the ordinary selector "section div div", while the fixed version 4.0 answered in under 0.01 seconds. A document of just 200 nested div tags, about 1 KB, took 40.9 seconds against a selector with three descendant combinators. A proof of concept is publicly available.
Who is affected
Applications are affected if they run selectors with descendant combinators against documents that untrusted users can influence, such as web scrapers, HTML sanitisers or filters, and services that process uploaded or fetched markup. Descendant combinators are among the most common parts of CSS selectors, and a document of about 1 KB is enough to tie up a worker for close to a minute. Applications that only run selectors against trusted documents are not affected.
All versions of Soup Sieve before 4.0 are affected. A related flaw in the same library, CVE-2026-126192, was published on the same day with a CVSS score of 6.3, and is also fixed in version 4.0.
How to fix CVE-2026-126190
The fix is to upgrade the soupsieve Python package to version 4.0 or later, for example by running pip install --upgrade 'soupsieve>=4.0' in every affected environment and container image, then checking the installed version. Soup Sieve 4.0 caches whether an element is, or has an ancestor that is, a match for part of a selector, which makes each descendant combinator linear in the size of the document. Results are unchanged, and ordinary documents are no slower.
Caching is enabled by default, so no changes are needed beyond upgrading. The NOCACHE flag is a temporary fallback that uses the old uncached matching, so selectors compiled with NOCACHE are still subject to the polynomial slowdown and should not be used with descendant combinators on untrusted input.
If an immediate upgrade is not possible, the advisory suggests using as few descendant combinators as possible in selectors that run on untrusted documents, using the child combinator (>) instead where the structure of the document is known, limiting the size and nesting depth of untrusted documents before selecting on them, and running selection on untrusted input with a time limit, for example in a worker process that can be stopped.
Sources: GitHub Security Advisory and CVE Reports on dev.to