{"id":"CVE-2026-66293","kind":"vulnerability","aliases":["CVE-2026-66293"],"related":[],"title":"Saxy: XML comments let attacker-supplied text inject markup","description":"XML injection in the encoder of Saxy. Saxy.Encoder does not neutralize the -- sequence in XML comment content: escape_comment/2 returns the comment binary unchanged in every clause and only appends a space when the comment ends in a single -, so neither an interior -- nor a full --> is escaped or rejected before the encoder wraps the content in the <!-- and --> delimiters.\n\nWhen an application serializes attacker-controlled text as a comment, through Saxy.XML.comment/1 or a raw {:comment, text} simple form child, the attacker can close the comment early with --> and inject arbitrary sibling markup into the serialized document. A downstream parser then sees elements, attributes, and text that the application never built. Where the document is rendered as HTML or SVG, the injected markup executes as stored cross-site scripting; where it is consumed by another XML processor, the attacker can forge data that the producing application never emitted. Documents that Saxy only parses are not a vector.\n\nThis issue affects saxy: from 0.7.0 before 1.7.0.","summary":"Saxy is an Elixir XML library whose encoder does not escape the -- sequence or --> inside comment content. An attacker who controls text serialized as a comment can close the comment early and inject arbitrary elements that downstream parsers or browsers will treat as real markup.","severity":"low","cvss":2.1,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["elixir","package","saxy","xml"],"not_affected_if":["no-untrusted-comment-text","parse-only","saxy-1.7.0-or-later"],"how_to_check":"- Look for `saxy` in `mix.lock` and note the locked version.\n- Search the codebase for `Saxy.XML.comment(` and for `{:comment,` in simple form children, and check whether any attacker-controlled text reaches them.","fix":"- `saxy` moves to `1.7.0` or later (affected range: from `0.7.0` before `1.7.0`).","status":"open","published_at":"2026-11-06T11:17:16+00:00","first_seen_at":"2026-11-06T11:41:29+00:00","triaged_at":"2026-11-06T11:43:59+00:00","updated_at":"2026-11-06T11:44:00+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-06T11:43:59Z","model":"claude-haiku-5-5","output":{"fix":"- `saxy` moves to `1.7.0` or later (affected range: from `0.7.0` before `1.7.0`).","reach":"unknown","title":"Saxy: XML comments let attacker-supplied text inject markup","impact":"medium","summary":"Saxy is an Elixir XML library whose encoder does not escape the -- sequence or --> inside comment content. An attacker who controls text serialized as a comment can close the comment early and inject arbitrary elements that downstream parsers or browsers will treat as real markup.","audience":"developers","category":"package","nicknames":[],"who_cares":["elixir","saxy","xml"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"attacker injects markup that runs as script in rendered output","analyst_note":"","how_to_check":"- Look for `saxy` in `mix.lock` and note the locked version.\n- Search the codebase for `Saxy.XML.comment(` and for `{:comment,` in simple form children, and check whether any attacker-controlled text reaches them.","plain_action":"","needs_analyst":false,"not_affected_if":["parse-only","no-untrusted-comment-text","saxy-1.7.0-or-later"],"who_is_affected":"Only applications that build XML with Saxy's encoder and place untrusted text inside comments, via Saxy.XML.comment/1 or a raw {:comment, text} child. Applications that only parse XML with Saxy are not a vector. The rendered output matters: if a browser or another XML processor reads the generated document as HTML or SVG, injected markup can run as stored cross-site scripting.","user_interaction":"unknown","needs_special_setup":"no","severity_if_unknown":"low"},"cost_usd":0.000747,"input_tokens":4487,"output_tokens":596,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-2026':12A,15A '-66293':13A,16A '/1':139C '0.7.0':231C '1.7.0':233C 'affect':228C 'anoth':203C 'append':95C 'applic':127C,176C,214C 'arbitrari':54B,158C 'attack':6A,39B,130C,149C,207C 'attacker-control':129C 'attacker-suppli':5A 'attribut':171C 'binari':88C 'browser':60B 'built':178C 'child':147C 'claus':92C 'close':48B,151C 'comment':3A,36B,46B,50B,81C,87C,100C,135C,143C,153C 'comment/2':84C 'consum':201C 'content':37B,82C,121C 'control':41B,131C 'cross':195C 'cross-sit':194C 'cve':11A,14A 'data':210C 'delimit':124C 'document':164C,181C,217C 'downstream':57B,166C 'earli':51B,154C 'element':55B,170C 'elixir':17B,24B 'emit':216C 'encod':28B,70C,118C 'end':101C 'escap':31B,83C,113C 'everi':91C 'execut':191C 'forg':209C 'form':146C 'full':111C 'html':185C 'inject':9A,53B,67C,157C,189C 'insid':35B 'interior':108C 'issu':227C 'let':4A 'librari':26B 'markup':10A,65B,160C,190C 'neither':106C 'neutral':76C 'never':177C,215C 'packag':18B 'pars':221C 'parser':58B,167C 'processor':205C 'produc':213C 'raw':142C 'real':64B 'reject':115C 'render':183C 'return':85C 'saxi':1A,19B,21B,72C,219C,229C 'saxy.encoder':73C 'saxy.xml.comment':138C 'saxy.xml.comment/1':137C 'script':197C 'see':169C 'sequenc':33B,78C 'serial':43B,128C,163C 'sibl':159C 'simpl':145C 'singl':104C 'site':196C 'space':97C 'store':193C 'suppli':7A 'svg':187C 'text':8A,42B,132C,144C,173C 'treat':62B 'unchang':89C 'vector':225C 'whose':27B 'wrap':119C 'xml':2A,20B,25B,66C,80C,204C","nicknames":[],"mitigations":[],"who_affected":"Only applications that build XML with Saxy's encoder and place untrusted text inside comments, via Saxy.XML.comment/1 or a raw {:comment, text} child. Applications that only parse XML with Saxy are not a vector. The rendered output matters: if a browser or another XML processor reads the generated document as HTML or SVG, injected markup can run as stored cross-site scripting.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["elixir","low","package","saxy","xml"],"campaign_type":null,"search_a":"'-2026':12A,15A '-66293':13A,16A 'attack':6A 'attacker-suppli':5A 'comment':3A 'cve':11A,14A 'inject':9A 'let':4A 'markup':10A 'saxi':1A 'suppli':7A 'text':8A 'xml':2A","search_b":"'arbitrari':54B 'attack':39B 'browser':60B 'close':48B 'comment':36B,46B,50B 'content':37B 'control':41B 'downstream':57B 'earli':51B 'element':55B 'elixir':17B,24B 'encod':28B 'escap':31B 'inject':53B 'insid':35B 'librari':26B 'markup':65B 'packag':18B 'parser':58B 'real':64B 'saxi':19B,21B 'sequenc':33B 'serial':43B 'text':42B 'treat':62B 'whose':27B 'xml':20B,25B","search_c":"'/1':139C '0.7.0':231C '1.7.0':233C 'affect':228C 'anoth':203C 'append':95C 'applic':127C,176C,214C 'arbitrari':158C 'attack':130C,149C,207C 'attacker-control':129C 'attribut':171C 'binari':88C 'built':178C 'child':147C 'claus':92C 'close':151C 'comment':81C,87C,100C,135C,143C,153C 'comment/2':84C 'consum':201C 'content':82C,121C 'control':131C 'cross':195C 'cross-sit':194C 'data':210C 'delimit':124C 'document':164C,181C,217C 'downstream':166C 'earli':154C 'element':170C 'emit':216C 'encod':70C,118C 'end':101C 'escap':83C,113C 'everi':91C 'execut':191C 'forg':209C 'form':146C 'full':111C 'html':185C 'inject':67C,157C,189C 'interior':108C 'issu':227C 'markup':160C,190C 'neither':106C 'neutral':76C 'never':177C,215C 'pars':221C 'parser':167C 'processor':205C 'produc':213C 'raw':142C 'reject':115C 'render':183C 'return':85C 'saxi':72C,219C,229C 'saxy.encoder':73C 'saxy.xml.comment':138C 'saxy.xml.comment/1':137C 'script':197C 'see':169C 'sequenc':78C 'serial':128C,163C 'sibl':159C 'simpl':145C 'singl':104C 'site':196C 'space':97C 'store':193C 'svg':187C 'text':132C,144C,173C 'unchang':89C 'vector':225C 'wrap':119C 'xml':66C,80C,204C","first_public_at":"2026-11-06T11:17:16+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:L/AC:L/AT:P/PR:N/UI:N/VC:N/VI:L/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":"6b3ad84c-e1a6-4bf7-a703-f496b71e49db","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-66293","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-66293","severity":null,"published_at":"2026-11-06T11:17:16+00:00","modified_at":"2026-11-06T11:17:16+00:00","first_seen_at":"2026-11-06T11:41:29+00:00","fetched_at":"2026-11-06T11:41:29+00:00","note":null}],"documents":[{"id":85903,"url":"https://github.com/qcam/saxy/commit/6d12ee12b9e32e86ef598b3f3cafccd1840b2f41","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":85905,"url":"https://github.com/qcam/saxy/commit/7266632e9407842f28ffac254c56dc41210a5690","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":85906,"url":"https://github.com/qcam/saxy/security/advisories/GHSA-mm3m-xwmf-v698","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}