{"id":"CVE-2026-126208","kind":"vulnerability","aliases":["CVE-2026-126208","GHSA-345x-3rq2-jfrm"],"related":[],"title":"Loofah: SVG `<textPath>` and `<mpath>` bypass local-reference restriction","description":"## Summary\n\nLoofah restricts `href` and `xlink:href` on certain SVG elements to same-document references. Two elements escaped the restriction:\n\n- `<textPath>`: `SVG_ALLOW_LOCAL_HREF` listed it in lowercase as `textpath`, but the HTML5 parser names the element `textPath` inside `<svg>`, so the check never matched on the HTML5 path.\n- `<mpath>`: absent from `SVG_ALLOW_LOCAL_HREF`, so its references were never restricted on either path.\n\n`rails-html-sanitizer` reuses this safelist in its `PermitScrubber`, so it is affected too.\n\n## Impact\n\nAn external `href` or `xlink:href` on `<textPath>` or `<mpath>` survives sanitization. Firefox fetches the URL when rendering the content, which leaks the viewer's IP address, user agent, and referrer, and can reach hosts routable only from the viewer's network. Chrome and WebKit do not fetch external references on these elements. The impact is a network request to an attacker-chosen URL, not script execution.\n\nApplications that sanitize user-supplied SVG, directly or inside HTML, with Loofah's default allowlist or with `rails-html-sanitizer` with SVG elements permitted are affected.\n\n## Mitigation\n\nUpgrade to Loofah >= 2.25.3.","summary":"Loofah's HTML sanitizer lets external href and xlink:href values survive on SVG textPath and mpath elements. When a user-supplied SVG is rendered in Firefox, the viewer's browser fetches the attacker's URL, leaking IP address, user agent and referrer.","severity":"medium","cvss":4.7,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"loofah","fixed":["2.25.3"],"affected":"< 2.25.3","ecosystem":"rubygems"}],"ecosystems":["rubygems"],"tags":["cwe-178","cwe-184","loofah","package","rails","rails-html-sanitizer","ruby"],"not_affected_if":["no-user-svg","static-content"],"how_to_check":"- Check the Loofah version in `Gemfile.lock` or with `bundle list | grep loofah`\n- Check whether `rails-html-sanitizer` is in `Gemfile.lock` and whether `PermitScrubber` is configured to allow SVG elements\n- Look for code that sanitizes user-supplied SVG or HTML containing SVG","fix":"- loofah: upgrade to `2.25.3` or later\n- rails-html-sanitizer: the sources do not name a fixed version","status":"open","published_at":"2026-11-12T21:17:22+00:00","first_seen_at":"2026-11-12T21:29:45+00:00","triaged_at":"2026-11-12T21:31:48+00:00","updated_at":"2026-11-12T21:40:31+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-12T21:31:48Z","model":"claude-haiku-5-5","output":{"fix":"- loofah: upgrade to `2.25.3` or later\n- rails-html-sanitizer: the sources do not name a fixed version","reach":"internet","title":"Loofah: SVG textPath and mpath bypass sanitizer's local-reference restriction","impact":"low","summary":"Loofah's HTML sanitizer lets external href and xlink:href values survive on SVG textPath and mpath elements. When a user-supplied SVG is rendered in Firefox, the viewer's browser fetches the attacker's URL, leaking IP address, user agent and referrer.","audience":"developers","category":"package","nicknames":[],"who_cares":["ruby","rails","loofah","rails-html-sanitizer"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"viewer's IP address and referrer leak to attacker-chosen URL","analyst_note":"","how_to_check":"- Check the Loofah version in `Gemfile.lock` or with `bundle list | grep loofah`\n- Check whether `rails-html-sanitizer` is in `Gemfile.lock` and whether `PermitScrubber` is configured to allow SVG elements\n- Look for code that sanitizes user-supplied SVG or HTML containing SVG","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["no-user-svg","static-content"],"who_is_affected":"Applications that sanitize user-supplied SVG, directly or inside HTML, using Loofah's default allowlist, or rails-html-sanitizer with SVG elements permitted, are affected. Impact is a network request to an attacker-chosen URL, not script execution. Chrome and WebKit do not fetch external references on these elements.","user_interaction":"yes","product_ecosystem":"","needs_special_setup":"unknown","severity_if_unknown":"unknown"},"cost_usd":0.000829,"input_tokens":5040,"output_tokens":649,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-126208':11A,19A '-178':22B '-184':24B '-2026':10A,18A '2.25.3':255C '345x':14A '3rq2':15A 'absent':126C 'address':72B,181C 'affect':154C,250C 'agent':74B,183C 'allow':99C,129C 'allowlist':238C 'applic':223C 'attack':67B,217C 'attacker-chosen':216C 'browser':64B 'bypass':4A 'certain':85C 'check':119C 'chosen':218C 'chrome':197C 'content':174C 'cve':9A,17A 'cwe':21B,23B 'default':237C 'direct':230C 'document':91C 'either':139C 'element':50B,87C,94C,114C,207C,247C 'escap':95C 'execut':222C 'extern':38B,158C,203C 'fetch':65B,168C,202C 'firefox':60B,167C 'ghsa':13A 'ghsa-345x-3rq2-jfrm':12A 'host':189C 'href':39B,42B,80C,83C,101C,131C,159C,162C 'html':30B,35B,143C,233C,243C 'html5':110C,124C 'impact':156C,209C 'insid':116C,232C 'ip':71B,180C 'jfrm':16A 'leak':70B,176C 'let':37B 'list':102C 'local':6A,100C,130C 'local-refer':5A 'loofah':1A,20A,25B,33B,78C,235C,254C 'lowercas':105C 'match':121C 'mitig':251C 'mpath':49B 'name':112C 'network':196C,212C 'never':120C,136C 'packag':26B 'parser':111C 'path':125C,140C 'permit':248C 'permitscrubb':150C 'rail':27B,29B,142C,242C 'rails-html-sanit':28B,141C,241C 'reach':188C 'refer':7A,92C,134C,204C 'referr':76B,185C 'render':58B,172C 'request':213C 'restrict':8A,79C,97C,137C 'reus':145C 'routabl':190C 'rubi':32B 'safelist':147C 'same-docu':89C 'sanit':31B,36B,144C,166C,225C,244C 'script':221C 'summari':77C 'suppli':55B,228C 'surviv':44B,165C 'svg':2A,46B,56B,86C,98C,128C,229C,246C 'textpath':47B,107C,115C 'two':93C 'upgrad':252C 'url':69B,170C,219C 'user':54B,73B,182C,227C 'user-suppli':53B,226C 'valu':43B 'viewer':62B,178C,194C 'webkit':199C 'xlink':41B,82C,161C","nicknames":[],"mitigations":[],"who_affected":"Applications that sanitize user-supplied SVG, directly or inside HTML, using Loofah's default allowlist, or rails-html-sanitizer with SVG elements permitted, are affected. Impact is a network request to an attacker-chosen URL, not script execution. Chrome and WebKit do not fetch external references on these elements.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["loofah"],"ptokens":["loofah"],"labels":["cwe178","cwe184","loofah","medium","package","rails","railshtmlsanitizer","ruby","rubygems"],"campaign_type":null,"search_a":"'-126208':11A,19A '-2026':10A,18A '345x':14A '3rq2':15A 'bypass':4A 'cve':9A,17A 'ghsa':13A 'ghsa-345x-3rq2-jfrm':12A 'jfrm':16A 'local':6A 'local-refer':5A 'loofah':1A,20A 'refer':7A 'restrict':8A 'svg':2A","search_b":"'-178':22B '-184':24B 'address':72B 'agent':74B 'attack':67B 'browser':64B 'cwe':21B,23B 'element':50B 'extern':38B 'fetch':65B 'firefox':60B 'href':39B,42B 'html':30B,35B 'ip':71B 'leak':70B 'let':37B 'loofah':25B,33B 'mpath':49B 'packag':26B 'rail':27B,29B 'rails-html-sanit':28B 'referr':76B 'render':58B 'rubi':32B 'sanit':31B,36B 'suppli':55B 'surviv':44B 'svg':46B,56B 'textpath':47B 'url':69B 'user':54B,73B 'user-suppli':53B 'valu':43B 'viewer':62B 'xlink':41B","search_c":"'2.25.3':255C 'absent':126C 'address':181C 'affect':154C,250C 'agent':183C 'allow':99C,129C 'allowlist':238C 'applic':223C 'attack':217C 'attacker-chosen':216C 'certain':85C 'check':119C 'chosen':218C 'chrome':197C 'content':174C 'default':237C 'direct':230C 'document':91C 'either':139C 'element':87C,94C,114C,207C,247C 'escap':95C 'execut':222C 'extern':158C,203C 'fetch':168C,202C 'firefox':167C 'host':189C 'href':80C,83C,101C,131C,159C,162C 'html':143C,233C,243C 'html5':110C,124C 'impact':156C,209C 'insid':116C,232C 'ip':180C 'leak':176C 'list':102C 'local':100C,130C 'loofah':78C,235C,254C 'lowercas':105C 'match':121C 'mitig':251C 'name':112C 'network':196C,212C 'never':120C,136C 'parser':111C 'path':125C,140C 'permit':248C 'permitscrubb':150C 'rail':142C,242C 'rails-html-sanit':141C,241C 'reach':188C 'refer':92C,134C,204C 'referr':185C 'render':172C 'request':213C 'restrict':79C,97C,137C 'reus':145C 'routabl':190C 'safelist':147C 'same-docu':89C 'sanit':144C,166C,225C,244C 'script':221C 'summari':77C 'suppli':228C 'surviv':165C 'svg':86C,98C,128C,229C,246C 'textpath':107C,115C 'two':93C 'upgrad':252C 'url':170C,219C 'user':182C,227C 'user-suppli':226C 'viewer':178C,194C 'webkit':199C 'xlink':82C,161C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-02T05:03:43+00:00","kev":null,"cvss_vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:N/A:N","cvss_by":"GitHub","poc_count":0,"sources":[{"source":"ghsa","external_id":"GHSA-345x-3rq2-jfrm","url":"https://github.com/advisories/GHSA-345x-3rq2-jfrm","severity":"medium","published_at":"2026-11-12T21:26:53+00:00","modified_at":"2026-11-12T21:27:48+00:00","first_seen_at":"2026-11-12T21:29:45+00:00","fetched_at":"2026-11-12T21:38:38+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-126208","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-126208","severity":null,"published_at":"2026-11-12T21:17:22+00:00","modified_at":"2026-11-12T21:17:22+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":139200,"url":"https://api.github.com/repos/flavorjones/loofah/security-advisories/GHSA-345x-3rq2-jfrm","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":139201,"url":"https://github.com/flavorjones/loofah/security/advisories/GHSA-345x-3rq2-jfrm","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa","publisher":"vendor","text":null,"published_at":"2026-11-02T05:03:43+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":139203,"url":"https://github.com/flavorjones/loofah/commit/cdd6ff7fb51998eb181bd2da925ddbcfcc8a3b96","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"}