{"id":"CVE-2026-63430","kind":"vulnerability","aliases":["CVE-2026-63430","GHSA-9jh8-v38h-cvhr"],"related":[],"title":"ammonia: mXSS  via MathML `annotation-xml` encoding strip","description":"If a certain set of MathML tags are enabled, an attacker can inject arbitrary JavaScript code into the user's browser.\n\nThe `annotation-xml` tag has slightly different behavior than the other \"integration point\"\ntags in MathML and SVG, but ammonia didn't handle it, so it didn't correctly\nstrip the namespace-incompatible tags.\n\nThis vulnerability only has an effect when the `math` and `annotation-xml` tags\nare both enabled, but the `encoding` attribute is disabled, because it relies\non the following sequence of steps:\n\n1. User writes code like `<math><annotation-xml encoding=\"text/html\"><gadget></annotation-xml></math>`.\n2. Namespace filtering checks the DOM, and it passes. `<gadget>` is parsed as HTML.\n3. Attribute filter strips it down to `<math><annotation-xml><gadget></annotation-xml></math>`. Because the encoding attribute is gone, `<gadget>` is now parsed as MathML.\n4. The gadget is written in such a way that it exploits the parsing differences between HTML and MathML.\n\nAdditionally, the gadget can only be written using a tag that is parsed as raw text in HTML.\nThese [elements] are:\n\n* title\n* textarea\n* xmp\n* iframe\n* noembed\n* noframes\n* plaintext\n* noscript\n* style\n* script\n\nApplications that do not explicitly allow any of these tags should not be affected, since none are allowed by default.\n\n[elements]: https://github.com/servo/html5ever/blob/045a0378f2b0f8d4a350793899cf722a2a9b3d11/html5ever/src/tree_builder/rules.rs\n\n### Impact\n\nLow: Requires both MathML and at least one raw-text HTML tag to be enabled, and most websites don't enable either of those.\n\n### Patches\n\n- https://github.com/rust-ammonia/ammonia/pull/245 (released in 4.1.3)\n- https://github.com/rust-ammonia/ammonia/pull/244 (released in 4.0.2)\n- https://github.com/rust-ammonia/ammonia/pull/243 (released in 3.3.2)\n\n### Workarounds\n\nCall <code>builder.[add_clean_content_tags](https://docs.rs/ammonia/latest/ammonia/struct.Builder.html#method.add_clean_content_tags)(\"annotation-xml\")</code> to remove the annotation-xml element and all of its children, including the XSS gadget.","summary":"ammonia is a Rust HTML sanitizer, and this flaw lets crafted MathML markup slip past its filter when the math and annotation-xml tags are both allowed and the encoding attribute is not. A remote attacker who gets such input through the sanitizer can run arbitrary JavaScript in the victim's browser.","severity":"medium","cvss":6.3,"epss":0.005539999809116125,"exploited":false,"exploited_at":null,"products":[{"name":"ammonia","fixed":["3.3.2"],"affected":"< 3.3.2","ecosystem":"cargo"},{"name":"ammonia","fixed":["4.0.2"],"affected":">= 4.0.0, < 4.0.2","ecosystem":"cargo"},{"name":"ammonia","fixed":["4.1.3"],"affected":">= 4.1.0, < 4.1.3","ecosystem":"cargo"}],"ecosystems":["cargo"],"tags":["ammonia","cwe-79","html-sanitization","package","rust","web-apps"],"not_affected_if":["annotation-xml-not-allowed","default-config","encoding-attribute-allowed","math-not-allowed"],"how_to_check":"Check Cargo.lock for ammonia versions below 3.3.2, 4.0.2 (for 4.0.x), or 4.1.3 (for 4.1.x).\nCheck builder code for allowed tags: look for add_tags or tags containing \"math\" and \"annotation-xml\" without the encoding attribute allowed.","fix":"Upgrade ammonia to 3.3.2, 4.0.2, or 4.1.3 depending on your major line.\nAs a workaround, call builder.add_clean_content_tags(\"annotation-xml\") to remove that element and its children.","status":"open","published_at":"2026-10-15T19:17:42+00:00","first_seen_at":"2026-10-23T19:11:32+00:00","triaged_at":"2026-10-23T20:10:07+00:00","updated_at":"2026-10-23T23:44:52+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-10-23T20:10:07Z","model":"claude-haiku-5-5","output":{"fix":"Upgrade ammonia to 3.3.2, 4.0.2, or 4.1.3 depending on your major line.\nAs a workaround, call builder.add_clean_content_tags(\"annotation-xml\") to remove that element and its children.","summary":"ammonia is a Rust HTML sanitizer, and this flaw lets crafted MathML markup slip past its filter when the math and annotation-xml tags are both allowed and the encoding attribute is not. A remote attacker who gets such input through the sanitizer can run arbitrary JavaScript in the victim's browser.","category":"package","who_cares":["rust","ammonia","html-sanitization","web-apps"],"confidence":0.8,"analyst_note":"","how_to_check":"Check Cargo.lock for ammonia versions below 3.3.2, 4.0.2 (for 4.0.x), or 4.1.3 (for 4.1.x).\nCheck builder code for allowed tags: look for add_tags or tags containing \"math\" and \"annotation-xml\" without the encoding attribute allowed.\nunknown for any other configuration check beyond that.","needs_analyst":false,"not_affected_if":["math-not-allowed","annotation-xml-not-allowed","encoding-attribute-allowed","default-config"],"severity_if_unknown":"medium"},"cost_usd":0.000513,"input_tokens":2848,"output_tokens":456,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-2026':11A,19A '-63430':12A,20A '-79':26B '/ammonia/latest/ammonia/struct.builder.html#method.add_clean_content_tags)(':341C '/rust-ammonia/ammonia/pull/243':328C '/rust-ammonia/ammonia/pull/244':322C '/rust-ammonia/ammonia/pull/245':316C '/servo/html5ever/blob/045a0378f2b0f8d4a350793899cf722a2a9b3d11/html5ever/src/tree_builder/rules.rs':286C '1':177C '2':182C '3':195C '3.3.2':331C '4':213C '4.0.2':325C '4.1.3':319C '9jh8':15A 'add':335C 'addit':232C 'affect':276C 'allow':62B,268C,280C 'ammonia':1A,21A,22A,23A,24B,35B,129C 'annot':6A,57B,111C,156C,343C,349C 'annotation-xml':5A,56B,110C,155C,342C,348C 'app':34B 'applic':263C 'arbitrari':81B,101C 'attack':71B,98C 'attribut':66B,165C,196C,205C 'behavior':117C 'browser':87B,108C 'builder':334C 'call':333C 'certain':90C 'check':185C 'children':356C 'clean':336C 'code':103C,180C 'content':337C 'correct':138C 'craft':45B 'cve':10A,18A 'cvhr':17A 'cwe':25B 'default':282C 'didn':130C,136C 'differ':116C,227C 'disabl':167C 'docs.rs':340C 'docs.rs/ammonia/latest/ammonia/struct.builder.html#method.add_clean_content_tags)(':339C 'dom':187C 'effect':150C 'either':310C 'element':251C,283C,351C 'enabl':96C,161C,303C,309C 'encod':8A,65B,164C,204C 'explicit':267C 'exploit':224C 'filter':51B,184C,197C 'flaw':43B 'follow':173C 'gadget':215C,234C,360C 'get':73B 'ghsa':14A 'ghsa-9jh8-v38h-cvhr':13A 'github.com':285C,315C,321C,327C 'github.com/rust-ammonia/ammonia/pull/243':326C 'github.com/rust-ammonia/ammonia/pull/244':320C 'github.com/rust-ammonia/ammonia/pull/245':314C 'github.com/servo/html5ever/blob/045a0378f2b0f8d4a350793899cf722a2a9b3d11/html5ever/src/tree_builder/rules.rs':284C 'gone':207C 'handl':132C 'html':28B,39B,194C,229C,249C,299C 'html-sanit':27B 'ifram':256C 'impact':287C 'includ':357C 'incompat':143C 'inject':100C 'input':75B 'integr':121C 'javascript':82B,102C 'least':294C 'let':44B 'like':181C 'low':288C 'markup':47B 'math':54B,153C 'mathml':4A,46B,93C,125C,212C,231C,291C 'mxss':2A 'namespac':142C,183C 'namespace-incompat':141C 'noemb':257C 'nofram':258C 'none':278C 'noscript':260C 'one':295C 'packag':30B 'pars':192C,210C,226C,244C 'pass':190C 'past':49B 'patch':313C 'plaintext':259C 'point':122C 'raw':246C,297C 'raw-text':296C 'releas':317C,323C,329C 'reli':170C 'remot':70B 'remov':346C 'requir':289C 'run':80B 'rust':31B,38B 'sanit':29B,40B,78B 'script':262C 'sequenc':174C 'set':91C 'sinc':277C 'slight':115C 'slip':48B 'step':176C 'strip':9A,139C,198C 'style':261C 'svg':127C 'tag':59B,94C,113C,123C,144C,158C,241C,272C,300C,338C 'text':247C,298C 'textarea':254C 'titl':253C 'use':239C 'user':106C,178C 'v38h':16A 'via':3A 'victim':85B 'vulner':146C 'way':221C 'web':33B 'web-app':32B 'websit':306C 'workaround':332C 'write':179C 'written':217C,238C 'xml':7A,58B,112C,157C,344C,350C 'xmp':255C 'xss':359C","nicknames":[],"mitigations":[],"who_affected":null,"tier":null,"verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-15T19:17:42+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/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":"ghsa","external_id":"GHSA-9jh8-v38h-cvhr","url":"https://github.com/advisories/GHSA-9jh8-v38h-cvhr","severity":"medium","published_at":"2026-10-22T14:06:10+00:00","modified_at":"2026-10-22T14:06:14+00:00","first_seen_at":"2026-10-23T19:11:32+00:00","fetched_at":"2026-10-23T19:11:32+00:00","note":null},{"source":"nvd","external_id":"CVE-2026-63430","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-63430","severity":null,"published_at":"2026-10-15T19:17:42+00:00","modified_at":"2026-10-16T16:00:33+00:00","first_seen_at":"2026-10-23T23:44:52+00:00","fetched_at":"2026-10-23T23:44:52+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"}