Overview

a tooltip xss in wikimedia charts

July 2, 2026
3 min read

TL;DR

I got CVE-2026-14358 in Wikimedia’s MediaWiki Charts Extension.

This one was a stored XSS in chart tooltips.

The short version:

  • attacker-controlled data lived in a Data:*.tab field title
  • that title became the pie slice name
  • the pie tooltip formatter returned it into the tooltip output
  • ECharts rendered the tooltip in HTML mode
  • the field title could become active markup when the tooltip appeared

The public task title says the bug pretty directly:

Stored XSS in Wikimedia Chart pie tooltip via Data:*.tab field title

The fun part was that the sink was not the chart body itself. It was the tooltip path.

Where the value landed

The relevant code was in the Charts extension client-side renderer:

resources/ext.chart/render.js

The pie chart tooltip path used a custom formatter:

tooltipSpec.formatter = ( params ) => {
const value = yFormatter( params.value );
const percentage = params.percent !== null ?
` (${ formatPercent( params.percent / 100 ) })` :
'';
return ` ${ params.marker } ${ params.name }: ${ value }${ percentage }`;
};

The dangerous part was params.name.

For the affected chart shape, that value could be influenced by the field title from a Data:*.tab page. If the title contained HTML, the tooltip formatter treated it like normal text, but the tooltip renderer could still interpret the returned string as HTML.

That is the mismatch:

stored data title
-> chart series item name
-> params.name
-> tooltip formatter string
-> HTML tooltip renderer

Why it worked

The formatter looked harmless because it was just building a tooltip label.

But tooltip formatters are still output sinks.

Returning a string from the formatter is only safe if the renderer treats the string as text, or if every user-controlled piece has already been escaped before it reaches the formatter.

In this case, the field title was not safe enough for an HTML tooltip context.

So a payload in the field title could survive until the user interacted with the pie chart and caused the tooltip to render.

The patch

The public Gerrit change is small, which is exactly why I liked this bug.

The patch added one line to the tooltip specification:

const tooltipSpec = {
renderMode: 'richText',
valueFormatter: yFormatter
};

That changes the tooltip rendering mode away from HTML.

So the fix was not a huge sanitizer rewrite. It was making the tooltip renderer use a mode where the tooltip content is treated as rich text instead of live HTML.

The Gerrit change was:

SECURITY: Use richText render mode in tooltipFormatter

with the linked bug:

Bug: T430548
Change-Id: Ibdaa7c852ae83f562e84dddc9c96ad64e2152210

What made it interesting

This was one of those bugs where the source and sink are far enough apart that it does not look scary at first.

A field title sounds boring.

A chart tooltip also sounds boring.

But once the field title becomes params.name, and params.name is returned into an HTML tooltip string, the boundary changes. It is no longer just chart metadata. It is attacker-controlled text entering a browser-rendered HTML surface.

That is usually where XSS bugs hide: not in the obvious page title, but in the small UI feature that reuses the same data later.

Impact

The CVE record classifies this as:

  • CWE: CWE-79
  • CAPEC: CAPEC-63
  • Severity: Medium
  • CVSS 4.0 score: 6.9
  • Vector: CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:L/SC:L/SI:L/SA:L

The confirmed issue was stored XSS in the Charts extension tooltip path.

In practical terms, malicious chart data could cause JavaScript execution for users who viewed or interacted with the affected chart.

Versions

The CVE record lists the affected product as:

MediaWiki - Charts Extension

Affected versions were before the patched release lines:

1.43.9
1.44.6
1.45.4

So the safe answer is to update the Charts extension through the fixed MediaWiki release line.

Credit note

This was reported under my name:

Fase Rais Baradika / @Baradika

The public Phabricator task also notes the report context and CCs @Baradika as the author.

Reference