rustsec-2026-0193
Vulnerability from osv_rustsec
If a certain set of MathML tags are enabled, an attacker can inject arbitrary JavaScript code into the user's browser.
The annotation-xml tag has slightly different behavior than the other "integration point"
tags in MathML and SVG, but ammonia didn't handle it, so it didn't correctly
strip the namespace-incompatible tags.
This vulnerability only has an effect when the math and annotation-xml tags
are both enabled, but the encoding attribute is disabled, because it relies
on the following sequence of steps:
- User writes code like
<math><annotation-xml encoding="text/html"><gadget></annotation-xml></math>. - Namespace filtering checks the DOM, and it passes.
<gadget>is parsed as HTML. - 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. - The gadget is written in such a way that it exploits the parsing differences between HTML and MathML.
Additionally, the gadget can only be written using a tag that is parsed as raw text in HTML. These elements are:
- title
- textarea
- xmp
- iframe
- noembed
- noframes
- plaintext
- noscript
- style
- script
Applications that do not explicitly allow any of these tags should not be affected, since none are allowed by default.
Discovered by: ivan0912 (YesWeHack) · Date: 2026-06-29 · Found via local differential analysis and source review of ammonia's sanitisation pipeline; no third-party systems were tested.
{
"affected": [
{
"database_specific": {
"categories": [
"format-injection"
],
"cvss": null,
"informational": null
},
"ecosystem_specific": {
"affected_functions": null,
"affects": {
"arch": [],
"functions": [],
"os": []
}
},
"package": {
"ecosystem": "crates.io",
"name": "ammonia",
"purl": "pkg:cargo/ammonia"
},
"ranges": [
{
"events": [
{
"introduced": "0.0.0-0"
},
{
"fixed": "3.3.2"
},
{
"introduced": "4.0.0"
},
{
"fixed": "4.0.2"
},
{
"introduced": "4.1.0"
},
{
"fixed": "4.1.3"
}
],
"type": "SEMVER"
}
],
"versions": []
}
],
"aliases": [
"GHSA-9jh8-v38h-cvhr"
],
"database_specific": {
"license": "CC0-1.0"
},
"details": "If a certain set of MathML tags are enabled, an attacker can inject arbitrary JavaScript code into the user\u0027s browser.\n\nThe `annotation-xml` tag has slightly different behavior than the other \"integration point\"\ntags in MathML and SVG, but ammonia didn\u0027t handle it, so it didn\u0027t 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 `\u003cmath\u003e\u003cannotation-xml encoding=\"text/html\"\u003e\u003cgadget\u003e\u003c/annotation-xml\u003e\u003c/math\u003e`.\n2. Namespace filtering checks the DOM, and it passes. `\u003cgadget\u003e` is parsed as HTML.\n3. Attribute filter strips it down to `\u003cmath\u003e\u003cannotation-xml\u003e\u003cgadget\u003e\u003c/annotation-xml\u003e\u003c/math\u003e`. Because the encoding attribute is gone, `\u003cgadget\u003e` 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---\n\n**Discovered by:** ivan0912 (YesWeHack) \u00b7 **Date:** 2026-06-29 \u00b7 Found via local differential analysis and source review of ammonia\u0027s sanitisation pipeline; no third-party systems were tested.",
"id": "RUSTSEC-2026-0193",
"modified": "2026-07-01T05:03:44Z",
"published": "2026-06-30T12:00:00Z",
"references": [
{
"type": "PACKAGE",
"url": "https://crates.io/crates/ammonia"
},
{
"type": "ADVISORY",
"url": "https://rustsec.org/advisories/RUSTSEC-2026-0193.html"
}
],
"related": [],
"severity": [],
"summary": "mXSS in ammonia via MathML `annotation-xml` encoding strip"
}
Sightings
| Author | Source | Type | Date |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.