{"id":"CVE-2026-116695","kind":"vulnerability","aliases":["CVE-2026-116695"],"related":[],"title":"Crass Ruby CSS parser: bad URL handling lets sanitizers keep live CSS","description":"Crass is a Ruby CSS parser that is compliant with the CSS Syntax Level 3 specification. Prior to 1.0.8, Crass incorrectly treats a closing parenthesis after an escaped backslash as escaped while consuming the remnants of a bad URL. Crass therefore keeps declarations, style rules, or at-rules inside a bad URL token even though a browser treats them as live CSS. A sanitizer that parses untrusted CSS with Crass and reserializes it without rejecting the bad URL can allow CSS used for UI redress, external resource loading, or CSS-based data exfiltration, but this issue does not enable script execution in modern browsers. This issue is fixed in version 1.0.8.","summary":"Crass, a Ruby CSS parser, mishandles a closing parenthesis after an escaped backslash inside a bad URL token, so it keeps declarations, rules or at-rules that browsers would treat as live CSS. A sanitizer that uses Crass to reserialize untrusted CSS can let through UI redress, external resource loading or CSS-based data exfiltration, though script execution is not possible in modern browsers.","severity":"medium","cvss":5.3,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["crass","css-sanitizer","package","ruby"],"not_affected_if":["no-untrusted-css","trusted-stylesheets-only"],"how_to_check":"- Check the installed Crass version with `bundle exec gem list crass` or by reading `Gemfile.lock` for `crass`.\n- Search the codebase for `Crass` and `Crass.parse` to find where untrusted CSS is sanitized and reserialized.","fix":"- Upgrade the crass gem to `1.0.8` or later.\n- If you sanitize untrusted CSS, also reject or strip bad URL tokens before reserializing the output.","status":"open","published_at":"2026-10-27T21:18:05+00:00","first_seen_at":"2026-10-27T21:29:21+00:00","triaged_at":"2026-10-27T21:30:21+00:00","updated_at":"2026-10-27T21:30:21+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-10-27T21:30:21Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade the crass gem to `1.0.8` or later.\n- If you sanitize untrusted CSS, also reject or strip bad URL tokens before reserializing the output.","reach":"internet","title":"Crass Ruby CSS parser: bad URL handling lets sanitizers keep live CSS","impact":"medium","summary":"Crass, a Ruby CSS parser, mishandles a closing parenthesis after an escaped backslash inside a bad URL token, so it keeps declarations, rules or at-rules that browsers would treat as live CSS. A sanitizer that uses Crass to reserialize untrusted CSS can let through UI redress, external resource loading or CSS-based data exfiltration, though script execution is not possible in modern browsers.","category":"package","nicknames":[],"who_cares":["ruby","crass","css-sanitizer"],"confidence":0.7,"needs_auth":"unknown","worst_case":"Injected CSS causes UI redress or data exfiltration in sanitized output","analyst_note":"","how_to_check":"- Check the installed Crass version with `bundle exec gem list crass` or by reading `Gemfile.lock` for `crass`.\n- Search the codebase for `Crass` and `Crass.parse` to find where untrusted CSS is sanitized and reserialized.","needs_analyst":false,"not_affected_if":["no-untrusted-css","trusted-stylesheets-only"],"who_is_affected":"Applications that use Crass to parse untrusted CSS and then reserialize it in a sanitizer, such as user-supplied styles in email or HTML rendering, are exposed. Applications that never parse untrusted CSS with Crass, or that only parse trusted stylesheets, are unlikely to be affected.","user_interaction":"unknown","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000665,"input_tokens":3453,"output_tokens":640,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-116695':15A,18A '-2026':14A,17A '1.0.8':109C,203C '3':105C 'allow':171C 'at-rul':49B,137C 'backslash':37B,119C 'bad':5A,40B,128C,142C,168C 'base':79B,183C 'browser':53B,90B,148C,196C 'close':32B,114C 'compliant':99C 'consum':123C 'crass':1A,19B,25B,63B,91C,110C,130C,161C 'css':3A,12A,21B,28B,58B,67B,78B,95C,102C,153C,159C,172C,182C 'css-base':77B,181C 'css-sanit':20B 'cve':13A,16A 'data':80B,184C 'declar':46B,133C 'enabl':191C 'escap':36B,118C,121C 'even':145C 'execut':84B,193C 'exfiltr':81B,185C 'extern':73B,177C 'fix':200C 'handl':7A 'incorrect':111C 'insid':38B,140C 'issu':188C,198C 'keep':10A,45B,132C 'let':8A,69B 'level':104C 'live':11A,57B,152C 'load':75B,179C 'mishandl':30B 'modern':89B,195C 'packag':23B 'parenthesi':33B,115C 'pars':157C 'parser':4A,29B,96C 'possibl':87B 'prior':107C 'redress':72B,176C 'reject':166C 'remnant':125C 'reseri':65B,163C 'resourc':74B,178C 'rubi':2A,24B,27B,94C 'rule':47B,51B,135C,139C 'sanit':9A,22B,60B,155C 'script':83B,192C 'specif':106C 'style':134C 'syntax':103C 'therefor':131C 'though':82B,146C 'token':42B,144C 'treat':55B,112C,149C 'ui':71B,175C 'untrust':66B,158C 'url':6A,41B,129C,143C,169C 'use':62B,173C 'version':202C 'without':165C 'would':54B","nicknames":[],"mitigations":[],"who_affected":"Applications that use Crass to parse untrusted CSS and then reserialize it in a sanitizer, such as user-supplied styles in email or HTML rendering, are exposed. Applications that never parse untrusted CSS with Crass, or that only parse trusted stylesheets, are unlikely to be affected.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-27T21:18:05+00:00","kev":null,"cvss_vector":"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/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"security-advisories@github.com","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-116695","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-116695","severity":null,"published_at":"2026-10-27T21:18:05+00:00","modified_at":"2026-10-27T21:18:05+00:00","first_seen_at":"2026-10-27T21:29:21+00:00","fetched_at":"2026-10-27T21:29:21+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}