GHSA-c4rq-3m3g-8wgx
High · 7.5Nokogiri CSS selector tokenizer has regular expression backtracking
CVSS
7.5
EPSS
—
Published
May 6, 2026
CISA due date
—
Cloudanix analysis
A flaw in a common HTML/XML parsing library can let someone make affected applications slow down or stop responding by sending specially crafted search patterns.
- Exploitation
- Remote Authenticated
- Attacker needs
- Low Privilege
- Complexity
- Low
- Impact
- Denial Of Service
- Component
- Library
- Class
- Denial of service
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
Nokogiri’s CSS selector tokenizer uses regular expressions that can exhibit exponential backtracking when processing specially crafted CSS selector strings. An attacker who can supply selector input to affected Nokogiri APIs can cause excessive CPU consumption during parsing/tokenization, leading to a regular-expression denial of service. The affected code paths include string-literal tokenization for certain unterminated quoted strings, string-literal tokenization for hex-escape-heavy input, and identifier tokenization for hex-escape-heavy input. Public APIs that may route input through the vulnerable tokenizer include `Nokogiri::CSS.xpath_for`, `Node#css`, `Node#at_css`, `Searchable#search`, and `CSS::Parser#parse`.
Why it matters to the business
Applications that parse attacker-controlled or user-supplied CSS selectors with Nokogiri may become slow or unresponsive under a small number of malicious requests, affecting availability of web services, background workers, APIs, scraping pipelines, document-processing systems, or XML/HTML processing jobs. The issue is not known to be in CISA KEV and no exploit maturity is reported, but the denial-of-service impact can still be operationally significant where selector strings are exposed through search, filtering, scraping, transformation, or parsing features.
How an attack unfolds
An attacker first identifies an application feature that accepts or derives CSS selector strings and passes them to Nokogiri selector parsing routines. They then submit a crafted selector containing one of the problematic patterns, such as an unterminated quoted string or hex-escape-heavy content that triggers pathological regex backtracking in the tokenizer. When the application calls `Nokogiri::CSS.xpath_for`, `Node#css`, `Node#at_css`, `Searchable#search`, or `CSS::Parser#parse`, the tokenizer spends disproportionate CPU time attempting to match the input. Repeated submissions or concurrent requests can pin application workers, increase request latency, exhaust processing capacity, and cause partial or full service degradation.
How to fix it
Upgrade Nokogiri to a release that contains the tokenizer fixes for this advisory. If exact fixed versions are not available in the advisory data, consult the official Nokogiri security advisory and package metadata for the corrected version in the RubyGems or downstream packaging channel in use. Regenerate lockfiles and redeploy all applications, workers, containers, and build artifacts that bundle Nokogiri. As defense in depth, do not pass untrusted selector strings directly to Nokogiri; validate selector length and character composition, reject unterminated strings and excessive escape sequences, enforce request/body size limits, and apply execution timeouts or worker-level CPU safeguards around parsing operations.
How to confirm the fix worked
Confirm that all deployed Ruby applications and images resolve Nokogiri to a fixed version by checking `Gemfile.lock`, software bills of materials, container image scans, and runtime package inventory. Search code for use of `Nokogiri::CSS.xpath_for`, `Node#css`, `Node#at_css`, `Searchable#search`, and `CSS::Parser#parse`, then verify whether any call paths receive untrusted input. In staging, run representative malformed selector tests with strict safety controls and confirm parsing fails quickly rather than consuming sustained CPU. Validate that request limits, selector validation, and timeouts are enforced where user input can influence selectors.
Typical attack path
- Find an application endpoint, job, plugin, or integration that accepts user-controlled CSS selector input or builds selectors from user input.
- Craft a malicious CSS selector using unterminated quoted strings or hex-escape-rich strings/identifiers designed to trigger excessive regex backtracking.
- Submit the selector to the application through the exposed feature, API, form field, queue message, or integration input.
- Cause the application to invoke an affected Nokogiri CSS parsing method such as `Node#css`, `Node#at_css`, `Searchable#search`, `Nokogiri::CSS.xpath_for`, or `CSS::Parser#parse`.
- Repeat or parallelize requests to consume CPU across application workers and degrade or deny service.
How to detect it
To assess possible prior exploitation, review application access logs, API gateway logs, WAF logs, job queue payload metadata, and application error logs for repeated requests containing unusually long or malformed CSS selector strings. Focus on inputs with unterminated quotes, dense CSS hex escape sequences, or repeated backslash-hex patterns, especially when correlated with CPU spikes, request timeouts, 5xx responses, worker restarts, or queue backlog. Examine APM traces and profiler data for long execution time in Nokogiri CSS parsing methods, including `Nokogiri::CSS.xpath_for`, `Node#css`, `Node#at_css`, `Searchable#search`, and `CSS::Parser#parse`. Because this is a denial-of-service condition rather than code execution, durable host artifacts are unlikely; evidence is most likely to be in request logs, application performance telemetry, timeout exceptions, and process CPU metrics around the time of service degradation.
- Nokogiri::CSS.xpath_for
- CSS::Parser#parse
- Node#css
- Node#at_css
- Searchable#search
- Regexp timeout
- execution expired
- Net::ReadTimeout
- Rack::Timeout::RequestTimeoutException
- ActionController::RequestTimeout
- Service Unavailable
- HTTP 503
- HTTP 504
- \\[0-9A-Fa-f]{1,6}
- unterminated string
- unterminated quote
What your security team should do
- Inventory all applications, containers, and build artifacts using Nokogiri and prioritize externally reachable services or worker queues that process user-supplied HTML, XML, or CSS selector input.
- Upgrade Nokogiri to a fixed release and ensure lockfiles, base images, and dependency caches are refreshed before redeployment.
- Review application code for affected Nokogiri CSS parsing APIs and determine whether selector input is attacker-controlled or derived from attacker-controlled fields.
- Add input validation and length limits for any feature accepting CSS selectors, especially rejecting unterminated quotes and excessive CSS hex escapes.
- Monitor application CPU saturation, request latency, worker timeouts, queue backlog, and repeated parsing errors for signs of attempted denial-of-service activity.
- Add rate limiting and concurrency controls to endpoints or jobs that perform selector parsing on user-provided content.
- Because the issue is not currently listed in KEV and exploit maturity is reported as none, treat remediation as high priority for exposed selector-processing features and standard dependency hygiene for non-exposed internal-only usage.
The record
Nokogiri's CSS selector tokenizer contains regular expressions whose construction may result in exponential regex backtracking on adversarial selectors. Three ReDoS vectors are addressed in this release: 1. String-literal tokenization on certain unterminated quoted-string input. 2. String-literal tokenization on a separate class of hex-escape-rich input. 3. Identifier tokenization on hex-escape-rich input. The public CSS selector methods that funnel through the affected tokenizer are `Nokogiri::CSS.xpath_for`, `Node#css`, `Node#at_css`, `Searchable#search`, and `CSS::Parser#parse`.
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|
Related vulnerabilities
- CVE-2026-112901 Pillow is a Python imaging library. CWE-1333
- CVE-2026-106454 Twisted is an event-based framework for internet applications, supporting Python 3.6+. CWE-1333
- CVE-2026-77387 geopy is a geocoding library for Python. CWE-1333
- CVE-2026-102990 basic-ftp is an FTP client for Node.js. CWE-1333
- CVE-2026-102473 A flaw was found in dash. CWE-1333
- CVE-2026-102270 PyJWT is a Python implementation of JSON Web Token standards. CWE-1333
- CVE-2026-101906 Axios is a promise-based HTTP client for the browser and Node.js. CWE-1333
- CVE-2026-101903 Axios is a promise-based HTTP client for the browser and Node.js. CWE-1333