GHSA-fm7p-gw32-828p
MEDIUMGHSA-fm7p-gw32-828p is a medium-severity (CVSS 6.3) CWE-116 vulnerability in mathlive. O3 Security confirms whether GHSA-fm7p-gw32-828p is actually reachable in your code before you act, and blocks exploitation at runtime until you patch.
mathlive's Lack of Escaping of HTML allows for XSS
Blast Radius
mathliveReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects npm packages — download data is not available via public APIs for these ecosystems.
Description
Summary
Despite the 0.104.0 patch escaping attribute-bearing constructs (\htmlData, \href), text-content reflection was missed. The \text{}, \mbox{} commands accept arbitrary characters in their body and emit them raw and unescaped into both the HTML markup and the MathML output, leading to XSS.
Details
Box.toMarkup at src/core/box.ts:356 concatenates this.value into the rendered span without HTML-escaping. In text mode any literal character (<, >, &, ") is wrapped into a TextAtom whose value is the raw codepoint and lands in the markup unchanged. The MathML serializer at src/formats/atom-to-math-ml.ts is independently broken: xmlEscape deliberately omits the & rule, and scanText, case 'text', and the mode === 'text' early return all emit atom.value raw.
Both outputs flow into innerHTML sinks via the public API. <math-span> / <math-div> (src/public/math-static-elements.ts:331,407) bypass MathfieldElement.createHTML entirely. The editor and SSR paths route through createHTML, but its default value is the identity function (src/public/mathfield-element.ts:789).
PoC
- Go to https://mathlive.io/mathfield/demo/
- open DevTools console and paste:
const s = document.createElement('math-span');
s.style.display = 'block';
s.textContent = '\\text{<img src=x onerror=alert(1)>}';
document.body.appendChild(s);
s.scrollIntoView();
Equivalent payloads: \mbox{<img src=x onerror=alert(1)>}
or
import { convertLatexToMarkup } from 'mathlive';
document.body.innerHTML = convertLatexToMarkup('\\text{<img src=x onerror=alert(1)>}');
Impact
MathLive users who render untrusted mathematical expressions can encounter malicious input that runs arbitrary JavaScript.
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 📦npm | mathlive | all versions | 0.110.0 |
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for mathlive. O3's reachability analysis confirms whether the vulnerable code path is actually invoked in your application, so you act on real exposure instead of every transitive match.
Fix
Update mathlive to 0.110.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-fm7p-gw32-828p is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
How O3 protects you
O3 pinpoints whether GHSA-fm7p-gw32-828p is reachable in your code and exactly where to fix it, then blocks exploitation in production at runtime until the patched version is deployed.
Tailored to GHSA-fm7p-gw32-828p. Runtime protection reduces exposure until a permanent patch is applied and verified — it complements patching, it doesn't replace it.
Frequently Asked Questions
Is GHSA-fm7p-gw32-828p in your dependencies?
O3 detects GHSA-fm7p-gw32-828p across npm dependencies and uses function-level reachability to confirm whether the vulnerable code path is actually reachable — not just present. No false positives.