BTC
ETH
SOL
BNB
GOLD
XRP
DOGE
ADA
Back to home
Security

[LOW] Security Advisory: TeleJSON: DOM XSS via unsanitised constructor name in `new Function()` (telejson)

Telejson versions below 6.0.0, released in 2022, suffer from a DOM-based XSS flaw.

Telejson versions below 6.0.0, released in 2022, suffer from a DOM-based XSS flaw. Attackers inject crafted JSON payloads with a malicious _constructor-name_ property. Telejson’s parser passes this string directly into new Function() without checks, executing arbitrary JavaScript in the victim’s browser.

This hits applications using telejson for object serialization, especially those handling untrusted input like postMessage across iframes. Storybook, the main user, relies on telejson for cross-frame communication in its UI previews. If your app embeds Storybook or similar tools, check your dependency tree now.

How the Bug Works

Telejson’s parse() function employs a custom JSON reviver to rebuild JavaScript objects. For objects tagged with _constructor-name_, it constructs a prototype via new Function(). In vulnerable code from v5.3.3:

if (isObject(value) && value['_constructor-name_']) {
  const name = value['_constructor-name_'];
  if (name !== 'Object') {
    const Fn = new Function(`return function ${name}(){}`)();
    Object.setPrototypeOf(value, new Fn());
  }
}

Here, name comes straight from attacker-controlled JSON. Set it to alert(document.cookie), and it crafts a function like function alert(document.cookie)()(){}, then sets it as prototype. Any property access on the object triggers the code.

Delivery? Craft a JSON payload via postMessage from a malicious iframe or worker. Storybook’s iframe-heavy setup makes this straightforward. No server-side parsing needed—pure client-side DOM XSS.

Real-World Impact

Arbitrary JS means full DOM access: steal cookies, session tokens, or keystrokes. In Storybook contexts, attackers compromise dev tools, potentially leaking source code or auth tokens from previews. Storybook powers over 1 million npm weekly downloads indirectly via telejson, which itself sees 500k+. Many React/Vue/Angular projects pull it in unaware.

Why linger in 2024? Dependency hell. Tools like Storybook 6.x pinned older telejson. A quick npm ls telejson reveals if you’re exposed. CVSS? Low per advisory, but DOM XSS escalates fast in interactive apps. Skeptical note: prototypes rarely trigger without property access, but real apps do that constantly.

Beyond Storybook, telejson appears in XState, Ladle, and custom serializers. If you serialize functions or classes over postMessage/WebSockets, audit now. This echoes prototype pollution risks, but direct eval-like execution ups the ante.

Fix and Next Steps

Upgrade to telejson 6.0.0+. The patch adds two layers:

if (isObject(value) && value['_constructor-name_'] && options.allowFunction) {
  const name = value['_constructor-name_'];
  if (name !== 'Object') {
    const Fn = new Function(`return function ${name.replace(/[\W_]+/g, '')}(){}`)();
    Object.setPrototypeOf(value, new Fn());
  }
}

It strips non-word characters with /[\W_]+/g (whitelist alphanumerics) and requires options.allowFunction true. Effective against basic payloads, though edge cases like unicode might slip—test thoroughly. Default allowFunction is false, neutering the feature unless opted in.

Remediate: Run npm update telejson or yarn upgrade telejson@latest. Pin >=6.0.0 in package.json. Audit postMessage handlers for JSON parsing. CSP with unsafe-eval blocked helps, but new Function() bypasses strict modes often.

This matters because frontend serialization is ubiquitous yet overlooked. Dev tools like Storybook embed in prod previews (e.g., Netlify/Vercel). One compromised iframe steals everything. Upgrade today—two years post-fix is no excuse.

April 3, 2026 · 3 min · 4 views · Source: GitHub Security

Related