MathLive 0.111.2 quietly fixes the flaw behind the ChatGPT shared-link takeover; 92% of npm downloads are still older versions
MathLive, the open-source math-input library at the center of the shared-link ChatGPT account takeover we reported on October 31, has closed the hole in the library itself, not just in ChatGPT. MathLive 0.111.2, published to npm on October 31 at 20:38 UTC, three days after Parameter's write-up and the same day it spread widely, changes the defaults that made the attack possible. What it hasn't done is say so loudly: there is no GitHub security advisory and no CVE for it, and a week and a half later, about 92% of MathLive's npm downloads are still versions without the fix.
The change is commit db6e36f, "implement same-origin validation for virtual keyboard messages", by maintainer Arno Gourdol (arnog). It addresses each step of the chain Mukul Goyal described in "Do the Math: How We Took Over ChatGPT Accounts":
| What the exploit used | Before (0.111.1) | After (0.111.2) |
|---|---|---|
| Who may send keyboard messages | originValidator defaulted to "none": any origin |
defaults to "same-origin"; cross-origin peers must be allowed by a callback |
| Where the keyboard listened | window.top, when reachable |
its own window |
Raw HTML layouts over postMessage |
update-setting could replace layouts with arbitrary markup |
cross-window messages can only pick built-in layouts, "even with origin validation disabled" |
| Which frame controls the keyboard | any message could become the new command recipient | commands accepted only from the connected mathfield window; no takeover while the keyboard is visible |
A few smaller fixes ride along: unrelated opaque ("null") origins no longer count as the same origin, a wildcard is no longer accepted as a sender's origin, and rejected messages are now dropped silently instead of throwing. A new Playwright test file, keyboard-security.spec.ts, adds about 290 lines of tests for these cases.
One thing did not change. Parameter noted that MathfieldElement.createHTML, which looked like a sanitizer, simply passed the attacker's HTML through. It still does. The commit documents it instead: SECURITY.md now says createHTML "is an integration hook, not a built-in sanitizer" whose default "returns the supplied HTML unchanged", and that "a Trusted Types policy that simply returns its input does not sanitize that input." With cross-window layouts blocked, that matters only for HTML an application passes in itself, which is where the library now says it must come from trusted code.
Fixed, but quietly
MathLive does use GitHub's advisory system. Its repository lists four published advisories, the latest two from October 9 for XSS bugs fixed in 0.111.1 (GHSA-j6jx-5m69-9fcr and GHSA-2qv9-c8pw-j949). The postMessage fix is not among them. It appears only under "Security" in the 0.111.2 changelog, so npm audit, Dependabot and similar tools have nothing to flag for sites still on older versions.
That matters because the bug was never ChatGPT-specific. Any page that loads MathLive's virtual keyboard next to a frame it doesn't control, such as a user-generated embed, an ad or a sandboxed preview, had the same open message slot. OpenAI fixed its own frontends by October 26. Everyone else needs the library update.
We checked npm's per-version download counts for the last week (the registry's public versions endpoint). Of 450,820 downloads, 34,979 were 0.111.2 to 0.111.4, about 7.8%. The most downloaded version was 0.110.0 with 144,668, followed by 0.111.1 (62,955) and 0.109.2 (54,019). Download counts aren't installs: CI systems re-download constantly, and sites that load MathLive from a CDN don't show up here at all. Still, the split shows the fix hasn't reached most of the projects pulling the package.
Part of the reason is semver. For a 0.x package, a caret range like ^0.110.0 does not cross into 0.111, so the largest group, on 0.110.0, will not pick up the fix through a routine update. Projects on ^0.111.0 will. The fix is also a behavior change for anyone who shares a keyboard across origins on purpose: they now have to set targetOrigin and an originValidator allowlist on both sides, as the updated iframe example shows.
If your site embeds MathLive, the useful checks are short: upgrade to 0.111.2 or later, don't set originValidator to "none" or targetOrigin to "*" on pages with frames you don't trust, and treat custom keyboard layouts and keycaps as code, because MathLive renders them as HTML.
Comments
No comments yet. Be the first.