CVE-2026-116695: CSS Sanitizer Bypass via Bad URL Tokenization Differential in Crass
Vulnerability ID: CVE-2026-116695
CVSS Score: 5.3
Published: 2026-10-28
An interpretation conflict vulnerability (CWE-436) exists in the Ruby CSS parser library Crass prior to version 1.0.8. When consuming the remnants of a malformed URL token, the tokenizer erroneously checks the previously consumed character to determine if a valid escape sequence is present. Consequently, a closing parenthesis immediately following an escaped backslash sequence is treated as escaped by Crass, while spec-compliant web browsers treat the closing parenthesis as the end of the bad URL token. Downstream CSS sanitizers such as Sanitize, Loofah, and rails-html-sanitizer that rely on Crass to parse and reserialize untrusted CSS can be bypassed to inject arbitrary CSS declarations, style rules, and external @import directives.
TL;DR
Crass versions prior to 1.0.8 fail to terminate malformed URL tokens at a closing parenthesis following an escaped backslash (\\)). This creates a parser differential between server-side Ruby CSS sanitizers and client-side web browsers, allowing attackers to bypass CSS sanitization filters to perform UI redress, load external stylesheets, or exfiltrate sensitive page data via CSS selectors.
⚠️ Exploit Status: POC
Technical Details
- CVE / Advisory ID: CVE-2026-116695 / GHSA-pq4g-8rxf-4g29
- Vulnerability Class: CWE-436: Interpretation Conflict (Parser Differential)
- Affected Component: Crass::Tokenizer#consume_bad_url (crass < 1.0.8)
- Attack Vector: Network (Crafted CSS Payload in Untrusted Input)
- CVSS v4.0 Score: 5.3 Medium (CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N)
- EPSS Score: 0.353% (28.90th Percentile)
- Security Impact: CSS Sanitizer Bypass (UI Redress, External Resource Loading, CSS Data Exfiltration)
- Patched Version: crass 1.0.8
Affected Systems
- crass Ruby Gem (< 1.0.8)
- Sanitize Ruby Gem (<= 7.0.0 when using Crass < 1.0.8)
- Loofah Ruby Gem (when using Crass < 1.0.8)
- rails-html-sanitizer Ruby Gem (when using Crass < 1.0.8)
-
crass: >= 0.0.1, < 1.0.8 (Fixed in:
1.0.8)
Code Analysis
Commit: 689fc45
Fix bad URL token not terminating at ) after an escaped backslash
File: lib/crass/tokenizer.rb
@@ -277,9 +277,7 @@ def consume_bad_url
text = String.new
until @s.eos?
- if valid_escape?
- text << consume_escaped
- elsif valid_escape?(@s.peek(2))
+ if valid_escape?(@s.peek(2))
@s.consume
text << consume_escaped
else
Exploit Details
- GitHub: Official upstream regression test suite and reproduction payloads demonstrating bad_url token smuggling across properties and stylesheets.
Mitigation Strategies
- Upgrade the Crass Ruby gem to version 1.0.8 or later across all affected applications and services.
- Audit Gemfile.lock files in applications using Loofah, Sanitize, or rails-html-sanitizer to ensure transitive dependencies on Crass are updated.
- Implement Content Security Policy (CSP) headers restricting style-src, img-src, and font-src to prevent external stylesheet loading and CSS-based data exfiltration.
- Where immediate patching is impossible, reject or strip CSS inputs containing double backslashes (\) or malformed url() constructs before sanitization.
Remediation Steps:
- Locate all Ruby projects using
crassdirectly or transitively viasanitize,loofah, orrails-html-sanitizer. - Add or update the dependency constraint
gem 'crass', '>= 1.0.8'in the project'sGemfile. - Execute
bundle update crassto regenerateGemfile.lockwith version 1.0.8. - Verify that
Gemfile.lockspecifiescrass (1.0.8)or higher and redeploy the application.
References
- GitHub Security Advisory GHSA-pq4g-8rxf-4g29
- NVD - CVE-2026-116695 Detail
- CVE.org Record: CVE-2026-116695
- GitHub Commit: Fix bad URL token not terminating at ) after an escaped backslash
- Crass Release v1.0.8
- Ruby Advisory Database - GHSA-pq4g-8rxf-4g29
- W3C CSS Syntax Module Level 3: §4.3.15 Consume the remnants of a bad url
Read the full report for CVE-2026-116695 on our website for more details including interactive diagrams and full exploit analysis.
Top comments (0)