{"id":"CVE-2026-66294","kind":"vulnerability","aliases":["CVE-2026-66294"],"related":[],"title":"Saxy: untrusted text in CDATA nodes lets attackers inject XML markup","description":"XML injection in the Saxy XML encoder. Saxy.Encoder.cdata/1 serializes a {:cdata, characters} node by wrapping the supplied characters between <![CDATA[ and ]]> and passing the payload through byte for byte. The encoder's character-data and attribute-value paths escape the XML metacharacters <, >, &, \", and ', but the CDATA path applies no neutralization at all. XML provides no character escaping mechanism inside a CDATA section, so the only correct way to represent a ]]> substring is to split the section and rejoin it as ]]]]><![CDATA[>. Saxy neither performs that split nor rejects the substring.\n\nAn application that renders untrusted text as CDATA, by building the node with Saxy.XML.cdata/1 and serializing it with Saxy.encode!/2 or Saxy.encode_to_iodata!/2, therefore lets an attacker terminate the section at a position of their choosing. Everything supplied after the ]]> is emitted outside any CDATA context and is parsed as markup, so a single attacker-controlled text field becomes attacker-controlled document structure: arbitrary sibling elements and attributes that the application never built. Downstream consumers of the serialized document accept the injected markup as genuine. Services that generate SOAP envelopes, RSS or Atom feeds, sitemaps, SVG, or XML exports from user-supplied content can have trusted fields forged or overridden. Applications that never place untrusted text in a CDATA node are not affected.\n\nThis issue affects saxy: from 0.7.0 before 1.7.0.","summary":"The Saxy Elixir XML encoder writes CDATA node content without splitting on the ]]> sequence, so text containing that sequence ends the section. Anything after it is emitted as real markup, letting an attacker add or override XML elements and attributes.","severity":"low","cvss":2.1,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["elixir","package","rss","saxy","soap","xml"],"not_affected_if":["no-untrusted-cdata","not-on-affected-version"],"how_to_check":"- Look for `Saxy.XML.cdata/1` in the codebase, where the argument can come from user input.\n- Check the saxy version in `mix.lock` against the affected range `0.7.0` to before `1.7.0`.","fix":"- saxy: upgrade to `1.7.0` or later","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:57+00:00","updated_at":"2026-11-06T11:43:57+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-06T11:43:57Z","model":"claude-haiku-5-5","output":{"fix":"- saxy: upgrade to `1.7.0` or later","reach":"internet","title":"Saxy: untrusted text in CDATA nodes lets attackers inject XML markup","impact":"medium","summary":"The Saxy Elixir XML encoder writes CDATA node content without splitting on the ]]> sequence, so text containing that sequence ends the section. Anything after it is emitted as real markup, letting an attacker add or override XML elements and attributes.","audience":"developers","category":"package","nicknames":[],"who_cares":["elixir","saxy","xml","soap","rss"],"confidence":0.7,"fix_status":"available","needs_auth":"unknown","worst_case":"attacker injects arbitrary XML elements and attributes into documents","analyst_note":"","how_to_check":"- Look for `Saxy.XML.cdata/1` in the codebase, where the argument can come from user input.\n- Check the saxy version in `mix.lock` against the affected range `0.7.0` to before `1.7.0`.","plain_action":"","needs_analyst":false,"not_affected_if":["no-untrusted-cdata","not-on-affected-version"],"who_is_affected":"Applications that build CDATA nodes from untrusted text with Saxy and serialize them with Saxy.encode! or Saxy.encode_to_iodata!. Services generating SOAP, RSS or Atom feeds, sitemaps, SVG or XML exports from user content are the typical cases. Applications that never put untrusted text in a CDATA node are not affected.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"low"},"cost_usd":0.000748,"input_tokens":4672,"output_tokens":562,"severity_before":"low"},"analyst_status":null,"analyst_note":null,"search":"'-2026':13A,16A '-66294':14A,17A '/1':73C,173C '/2':179C,184C '0.7.0':293C '1.7.0':295C 'accept':243C 'add':57B 'affect':287C,290C 'anyth':46B 'appli':115C 'applic':159C,234C,275C 'arbitrari':227C 'atom':256C 'attack':8A,56B,188C,217C,223C 'attacker-control':216C,222C 'attribut':63B,103C,231C 'attribute-valu':102C 'becom':221C 'build':167C 'built':236C 'byte':92C,94C 'cdata':5A,30B,76C,85C,113C,128C,148C,165C,206C,283C 'charact':77C,83C,99C,123C 'character-data':98C 'choos':197C 'consum':238C 'contain':40B 'content':32B,267C 'context':207C 'control':218C,224C 'correct':133C 'cve':12A,15A 'data':100C 'document':225C,242C 'downstream':237C 'element':61B,229C 'elixir':18B,26B 'emit':50B,203C 'encod':28B,70C,96C 'end':43B 'envelop':253C 'escap':106C,124C 'everyth':198C 'export':262C 'feed':257C 'field':220C,271C 'forg':272C 'generat':251C 'genuin':248C 'inject':9A,65C,245C 'insid':126C 'iodata':183C 'issu':289C 'let':7A,54B,186C 'markup':11A,53B,212C,246C 'mechan':125C 'metacharact':109C 'neither':150C 'neutral':117C 'never':235C,277C 'node':6A,31B,78C,169C,284C 'outsid':204C 'overrid':59B 'overridden':274C 'packag':19B 'pars':210C 'pass':88C 'path':105C,114C 'payload':90C 'perform':151C 'place':278C 'posit':194C 'provid':121C 'real':52B 'reject':155C 'rejoin':145C 'render':161C 'repres':136C 'rss':20B,254C 'saxi':1A,21B,25B,68C,149C,291C 'saxy.encode':178C,181C 'saxy.encoder.cdata':72C 'saxy.encoder.cdata/1':71C 'saxy.xml.cdata':172C 'saxy.xml.cdata/1':171C 'section':45B,129C,143C,191C 'sequenc':37B,42B 'serial':74C,175C,241C 'servic':249C 'sibl':228C 'singl':215C 'sitemap':258C 'soap':22B,252C 'split':34B,141C,153C 'structur':226C 'substr':138C,157C 'suppli':82C,199C,266C 'svg':259C 'termin':189C 'text':3A,39B,163C,219C,280C 'therefor':185C 'trust':270C 'untrust':2A,162C,279C 'user':265C 'user-suppli':264C 'valu':104C 'way':134C 'without':33B 'wrap':80C 'write':29B 'xml':10A,23B,27B,60B,64C,69C,108C,120C,261C","nicknames":[],"mitigations":[],"who_affected":"Applications that build CDATA nodes from untrusted text with Saxy and serialize them with Saxy.encode! or Saxy.encode_to_iodata!. Services generating SOAP, RSS or Atom feeds, sitemaps, SVG or XML exports from user content are the typical cases. Applications that never put untrusted text in a CDATA node are not affected.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["elixir","low","package","rss","saxy","soap","xml"],"campaign_type":null,"search_a":"'-2026':13A,16A '-66294':14A,17A 'attack':8A 'cdata':5A 'cve':12A,15A 'inject':9A 'let':7A 'markup':11A 'node':6A 'saxi':1A 'text':3A 'untrust':2A 'xml':10A","search_b":"'add':57B 'anyth':46B 'attack':56B 'attribut':63B 'cdata':30B 'contain':40B 'content':32B 'element':61B 'elixir':18B,26B 'emit':50B 'encod':28B 'end':43B 'let':54B 'markup':53B 'node':31B 'overrid':59B 'packag':19B 'real':52B 'rss':20B 'saxi':21B,25B 'section':45B 'sequenc':37B,42B 'soap':22B 'split':34B 'text':39B 'without':33B 'write':29B 'xml':23B,27B,60B","search_c":"'/1':73C,173C '/2':179C,184C '0.7.0':293C '1.7.0':295C 'accept':243C 'affect':287C,290C 'appli':115C 'applic':159C,234C,275C 'arbitrari':227C 'atom':256C 'attack':188C,217C,223C 'attacker-control':216C,222C 'attribut':103C,231C 'attribute-valu':102C 'becom':221C 'build':167C 'built':236C 'byte':92C,94C 'cdata':76C,85C,113C,128C,148C,165C,206C,283C 'charact':77C,83C,99C,123C 'character-data':98C 'choos':197C 'consum':238C 'content':267C 'context':207C 'control':218C,224C 'correct':133C 'data':100C 'document':225C,242C 'downstream':237C 'element':229C 'emit':203C 'encod':70C,96C 'envelop':253C 'escap':106C,124C 'everyth':198C 'export':262C 'feed':257C 'field':220C,271C 'forg':272C 'generat':251C 'genuin':248C 'inject':65C,245C 'insid':126C 'iodata':183C 'issu':289C 'let':186C 'markup':212C,246C 'mechan':125C 'metacharact':109C 'neither':150C 'neutral':117C 'never':235C,277C 'node':78C,169C,284C 'outsid':204C 'overridden':274C 'pars':210C 'pass':88C 'path':105C,114C 'payload':90C 'perform':151C 'place':278C 'posit':194C 'provid':121C 'reject':155C 'rejoin':145C 'render':161C 'repres':136C 'rss':254C 'saxi':68C,149C,291C 'saxy.encode':178C,181C 'saxy.encoder.cdata':72C 'saxy.encoder.cdata/1':71C 'saxy.xml.cdata':172C 'saxy.xml.cdata/1':171C 'section':129C,143C,191C 'serial':74C,175C,241C 'servic':249C 'sibl':228C 'singl':215C 'sitemap':258C 'soap':252C 'split':141C,153C 'structur':226C 'substr':138C,157C 'suppli':82C,199C,266C 'svg':259C 'termin':189C 'text':163C,219C,280C 'therefor':185C 'trust':270C 'untrust':162C,279C 'user':265C 'user-suppli':264C 'valu':104C 'way':134C 'wrap':80C 'xml':64C,69C,108C,120C,261C","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:N/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-66294","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-66294","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":85907,"url":"https://github.com/qcam/saxy/commit/71d99fae12f1d6596f5edb57b71f26ba854f4d33","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":85909,"url":"https://github.com/qcam/saxy/security/advisories/GHSA-hq6g-j46w-wx72","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"}