{"id":"CVE-2026-126205","kind":"vulnerability","aliases":["CVE-2026-126205","GHSA-mf2j-8f84-cc9q"],"related":[],"title":"Loofah: Regular expression denial of service in the SVG local-reference check","description":"## Summary\n\nLoofah's HTML5 sanitizer restricts the `href` and `xlink:href` attributes of SVG reference elements to local references. That check matched the attribute value against `/^\\s*[^#\\s].*/m`. In Ruby `^` anchors to every line start and `\\s` matches newlines, so an all-whitespace value made the engine rescan the value from each of its line starts, taking time quadratic in its length.\n\nOnly Ruby 3.1 and earlier are affected. Ruby 3.2 added linear-time regexp matching, which makes the pattern linear.\n\n## Impact\n\nAn attacker who supplies HTML to be sanitized can consume CPU out of proportion to the input size, by sending an SVG reference element whose `href` or `xlink:href` is a long run of whitespace.\n\nThe default safelist allows the elements in `SVG_ALLOW_LOCAL_HREF`, so no configuration change is required.\n\n## Mitigation\n\nUpgrade to Loofah >= 2.25.3. Applications that cannot upgrade should run Ruby 3.2 or later, which matches the pattern in linear time.\n\n## Credit\n\nReported by scyoon through the Rails HackerOne program.","summary":"Loofah's HTML sanitizer checks SVG href and xlink:href values with a regular expression that takes time quadratic in the value's length on Ruby 3.1 and earlier. An attacker who submits HTML with a long run of whitespace in such an attribute can consume server CPU out of proportion to the input size.","severity":"medium","cvss":5.3,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"loofah","fixed":["2.25.3"],"affected":"< 2.25.3","ecosystem":"rubygems"}],"ecosystems":["rubygems"],"tags":["cwe-1333","cwe-400","html-sanitization","loofah","package","rails","ruby"],"not_affected_if":["no-untrusted-html","ruby-3.2-or-later"],"how_to_check":"- Run `ruby --version` and check whether it reports 3.1 or earlier.\n- Run `bundle exec ruby -e \"require 'loofah'; puts Loofah::VERSION\"` or check Gemfile.lock for `loofah` below `2.25.3`.\n- Find where your application passes untrusted HTML into Loofah sanitization.","fix":"- Upgrade `loofah` to `2.25.3` or later.\n- Applications that cannot upgrade should run Ruby `3.2` or later, which matches the pattern in linear time.","status":"open","published_at":"2026-11-12T21:00:42+00:00","first_seen_at":"2026-11-12T21:03:58+00:00","triaged_at":"2026-11-12T21:04:36+00:00","updated_at":"2026-11-12T21:04:36+00:00","category":"package","confidence":0.85,"triage":{"at":"2026-11-12T21:04:36Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade `loofah` to `2.25.3` or later.\n- Applications that cannot upgrade should run Ruby `3.2` or later, which matches the pattern in linear time.","reach":"internet","title":"Loofah: crafted whitespace in SVG href causes CPU-exhausting slowdown","impact":"low","summary":"Loofah's HTML sanitizer checks SVG href and xlink:href values with a regular expression that takes time quadratic in the value's length on Ruby 3.1 and earlier. An attacker who submits HTML with a long run of whitespace in such an attribute can consume server CPU out of proportion to the input size.","audience":"developers","category":"package","nicknames":[],"who_cares":["ruby","rails","loofah","html-sanitization"],"confidence":0.85,"fix_status":"available","needs_auth":"no","worst_case":"Attacker drives CPU use high by sending long whitespace attribute values","analyst_note":"","how_to_check":"- Run `ruby --version` and check whether it reports 3.1 or earlier.\n- Run `bundle exec ruby -e \"require 'loofah'; puts Loofah::VERSION\"` or check Gemfile.lock for `loofah` below `2.25.3`.\n- Find where your application passes untrusted HTML into Loofah sanitization.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["ruby-3.2-or-later","no-untrusted-html"],"who_is_affected":"Applications that use Loofah to sanitize user-supplied HTML are exposed when they run Ruby 3.1 or earlier, because the affected check runs on every SVG reference element with an href or xlink:href value. The default safelist allows those elements, so no special configuration is needed. Systems on Ruby 3.2 or later, or that never sanitize untrusted HTML, can skip it.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"no","severity_if_unknown":"unknown"},"cost_usd":0.000837,"input_tokens":4971,"output_tokens":680,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-126205':16A,24A '-1333':27B '-2026':15A,23A '-400':29B '/m':120C '2.25.3':233C '3.1':63B,158C '3.2':164C,241C '8f84':20A 'add':165C 'affect':162C 'all-whitespac':134C 'allow':215C,220C 'anchor':123C 'applic':234C 'attack':67B,178C 'attribut':80B,103C,115C 'cannot':236C 'cc9q':21A 'chang':226C 'check':13A,41B,112C 'configur':225C 'consum':82B,186C 'cpu':84B,187C 'credit':251C 'cve':14A,22A 'cwe':26B,28B 'default':213C 'denial':4A 'earlier':65B,160C 'element':107C,200C,217C 'engin':140C 'everi':125C 'express':3A,51B 'ghsa':18A 'ghsa-mf2j-8f84-cc9q':17A 'hackeron':258C 'href':43B,46B,99C,102C,202C,205C,222C 'html':31B,39B,70B,181C 'html-sanit':30B 'html5':95C 'impact':176C 'input':90B,193C 'later':243C 'length':60B,155C 'line':126C,148C 'linear':167C,175C,249C 'linear-tim':166C 'local':11A,109C,221C 'local-refer':10A 'long':73B,208C 'loofah':1A,25A,33B,37B,93C,232C 'made':138C 'make':172C 'match':113C,130C,170C,245C 'mf2j':19A 'mitig':229C 'newlin':131C 'packag':34B 'pattern':174C,247C 'program':259C 'proport':87B,190C 'quadrat':55B,152C 'rail':35B,257C 'refer':12A,106C,110C,199C 'regexp':169C 'regular':2A,50B 'report':252C 'requir':228C 'rescan':141C 'restrict':97C 'rubi':36B,62B,122C,157C,163C,240C 'run':74B,209C,239C 'safelist':214C 'sanit':32B,40B,96C,184C 'scyoon':254C 'send':196C 'server':83B 'servic':6A 'size':91B,194C 'start':127C,149C 'submit':69B 'summari':92C 'suppli':180C 'svg':9A,42B,105C,198C,219C 'take':53B,150C 'time':54B,151C,168C,250C 'upgrad':230C,237C 'valu':47B,58B,116C,137C,143C 'whitespac':76B,136C,211C 'whose':201C 'xlink':45B,101C,204C","nicknames":[],"mitigations":[],"who_affected":"Applications that use Loofah to sanitize user-supplied HTML are exposed when they run Ruby 3.1 or earlier, because the affected check runs on every SVG reference element with an href or xlink:href value. The default safelist allows those elements, so no special configuration is needed. Systems on Ruby 3.2 or later, or that never sanitize untrusted HTML, can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["loofah"],"ptokens":["loofah"],"labels":["cwe1333","cwe400","htmlsanitization","loofah","medium","package","rails","ruby","rubygems"],"campaign_type":null,"search_a":"'-126205':16A,24A '-2026':15A,23A '8f84':20A 'cc9q':21A 'check':13A 'cve':14A,22A 'denial':4A 'express':3A 'ghsa':18A 'ghsa-mf2j-8f84-cc9q':17A 'local':11A 'local-refer':10A 'loofah':1A,25A 'mf2j':19A 'refer':12A 'regular':2A 'servic':6A 'svg':9A","search_b":"'-1333':27B '-400':29B '3.1':63B 'attack':67B 'attribut':80B 'check':41B 'consum':82B 'cpu':84B 'cwe':26B,28B 'earlier':65B 'express':51B 'href':43B,46B 'html':31B,39B,70B 'html-sanit':30B 'input':90B 'length':60B 'long':73B 'loofah':33B,37B 'packag':34B 'proport':87B 'quadrat':55B 'rail':35B 'regular':50B 'rubi':36B,62B 'run':74B 'sanit':32B,40B 'server':83B 'size':91B 'submit':69B 'svg':42B 'take':53B 'time':54B 'valu':47B,58B 'whitespac':76B 'xlink':45B","search_c":"'/m':120C '2.25.3':233C '3.1':158C '3.2':164C,241C 'add':165C 'affect':162C 'all-whitespac':134C 'allow':215C,220C 'anchor':123C 'applic':234C 'attack':178C 'attribut':103C,115C 'cannot':236C 'chang':226C 'check':112C 'configur':225C 'consum':186C 'cpu':187C 'credit':251C 'default':213C 'earlier':160C 'element':107C,200C,217C 'engin':140C 'everi':125C 'hackeron':258C 'href':99C,102C,202C,205C,222C 'html':181C 'html5':95C 'impact':176C 'input':193C 'later':243C 'length':155C 'line':126C,148C 'linear':167C,175C,249C 'linear-tim':166C 'local':109C,221C 'long':208C 'loofah':93C,232C 'made':138C 'make':172C 'match':113C,130C,170C,245C 'mitig':229C 'newlin':131C 'pattern':174C,247C 'program':259C 'proport':190C 'quadrat':152C 'rail':257C 'refer':106C,110C,199C 'regexp':169C 'report':252C 'requir':228C 'rescan':141C 'restrict':97C 'rubi':122C,157C,163C,240C 'run':209C,239C 'safelist':214C 'sanit':96C,184C 'scyoon':254C 'send':196C 'size':194C 'start':127C,149C 'summari':92C 'suppli':180C 'svg':105C,198C,219C 'take':150C 'time':151C,168C,250C 'upgrad':230C,237C 'valu':116C,137C,143C 'whitespac':136C,211C 'whose':201C 'xlink':101C,204C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-02T05:04:11+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-mf2j-8f84-cc9q","url":"https://github.com/advisories/GHSA-mf2j-8f84-cc9q","severity":"medium","published_at":"2026-11-12T21:00:42+00:00","modified_at":"2026-11-12T21:00:43+00:00","first_seen_at":"2026-11-12T21:03:58+00:00","fetched_at":"2026-11-12T21:09:03+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-126205","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-126205","severity":null,"published_at":"2026-11-12T21:17:21+00:00","modified_at":"2026-11-12T21:17:21+00:00","first_seen_at":"2026-11-12T21:40:31+00:00","fetched_at":"2026-11-12T21:40:32+00:00","note":null}],"documents":[{"id":138496,"url":"https://api.github.com/repos/flavorjones/loofah/security-advisories/GHSA-mf2j-8f84-cc9q","title":"Maintainer's advisory: api.github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: api.github.com"},{"id":138497,"url":"https://github.com/flavorjones/loofah/security/advisories/GHSA-mf2j-8f84-cc9q","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-11-02T05:04:11+00:00","relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"},{"id":138468,"url":"https://github.com/flavorjones/loofah/pull/324","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":138499,"url":"https://github.com/flavorjones/loofah/commit/2f31e7fae36036c9882d3d0fae720e1014c57cd1","title":"Patch: github.com","kind":"other","source":"ghsa","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":137847,"url":"https://github.com/flavorjones/loofah/releases/tag/v2.25.3","title":"Release notes: github.com","kind":"release","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Release: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}