Page MenuHomePhabricator

CVE-2025-6596: Vector inserts portlet labels as HTML, allowing for stored XSS through system messages
Closed, ResolvedPublicSecurity

Description

The JS implementation for portlets in the Vector skin (both 2022 and legacy) inserts the text of portlet labels as HTML, allowing for stored XSS through system messages.

Reproduction

Via system messages

<script> tags do not work here due to the way the HTML is inserted.

  • Edit MediaWiki:vector-feature-custom-font-size-name to <img src="" onerror="alert('vector-feature-custom-font-size-name')">
  • Edit MediaWiki:vector-feature-limited-width-name to <img src="" onerror="alert('vector-feature-limited-width-name')">
  • Visit any page using Vector 2022.

image.png (155×409 px, 10 KB)

image.png (155×409 px, 10 KB)

Via JS

  • Run the following code in the browser console: mw.util.addPortlet( 'p-mytest', '<img src="" onerror="alert(1)">', '#p-views' ); (<script> tags do not work here due to the way the HTML is inserted)

Cause

In what appears to be code that wraps a portlet label in a div, the textContent of the label is taken and inserted into the innerHtml of a div, essentially unsanitizing any text inside of it:
Legacy: https://github.com/wikimedia/mediawiki-skins-Vector/blob/9567e80c627110d42d56ccdc832ecd476dd86ded/resources/skins.vector.legacy.js/portlets.js#L27
2022: https://github.com/wikimedia/mediawiki-skins-Vector/blob/9567e80c627110d42d56ccdc832ecd476dd86ded/resources/skins.vector.js/portlets.js#L28

Additional information

I discovered and reported a similar XSS in the Citizen skin earlier today, and both the vulnerability and the fix are already public, since I was not aware that this affects Vector as well: https://github.com/StarCitizenTools/mediawiki-skins-Citizen/security/advisories/GHSA-jwr7-992g-68mh
I randomly stumbled upon the same code in Vector later today and quickly realized that it is therefore vulnerable to the same vulnerability.

There may be more affected system messages or even potentially user input that could allow for cross-site-scripting, depending on whether other extensions and user scripts supply unsanitized user input to the addPortlet function.

MW: 1.45.0-alpha (b6993c3)
Vector: 1.0.0 (9567e80)

Event Timeline

Patch:


This is essentially the same fix I provided to Citizen earlier today.

Patch:


This is essentially the same fix I provided to Citizen earlier today.

CR+1, looks good and works locally. AFAICT there’s no reason to expect that message to require any parsing, so plain text should be fine.

sbassett added a project: SecTeam-Processed.
sbassett subscribed.

Patch LGTM. We're trying to deploy a couple other security patches later today, so I'll add this to the list. Thanks.

sbassett changed the task status from Open to In Progress.Jun 12 2025, 3:28 PM
sbassett triaged this task as Low priority.

Deployed (SAL wmf.4 and wmf.5) – I asked in the security channel if it would be okay for me to just do it directly and nobody objected.

sbassett added a parent task: Restricted Task.Jun 12 2025, 3:49 PM
sbassett moved this task from Security Patch To Deploy to Watching on the Security-Team board.

Deployed (SAL wmf.4 and wmf.5) – I asked in the security channel if it would be okay for me to just do it directly and nobody objected.

Ok, thanks! Since Vector is bundled, let's keep this task and patch private for now (no public backports) until the upcoming core security release (I've added this task under the tracking bug for said release).

Reedy renamed this task from Vector inserts portlet labels as HTML, allowing for stored XSS through system messages to CVE-2025-6596: Vector inserts portlet labels as HTML, allowing for stored XSS through system messages.Jun 24 2025, 11:27 PM

Change #1165079 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@REL1_43] T396685

https://gerrit.wikimedia.org/r/1165079

Change #1165107 had a related patch set uploaded (by Reedy; author: SomeRandomDeveloper):

[mediawiki/skins/Vector@master] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165107

Change #1165079 abandoned by Reedy:

[mediawiki/core@REL1_43] T396685

https://gerrit.wikimedia.org/r/1165079

Change #1165107 merged by jenkins-bot:

[mediawiki/skins/Vector@master] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165107

Change #1165124 had a related patch set uploaded (by Reedy; author: SomeRandomDeveloper):

[mediawiki/skins/Vector@REL1_44] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165124

Change #1165125 had a related patch set uploaded (by Reedy; author: SomeRandomDeveloper):

[mediawiki/skins/Vector@REL1_43] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165125

Change #1165126 had a related patch set uploaded (by Reedy; author: SomeRandomDeveloper):

[mediawiki/skins/Vector@REL1_42] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165126

Change #1165127 had a related patch set uploaded (by Reedy; author: SomeRandomDeveloper):

[mediawiki/skins/Vector@REL1_39] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165127

Change #1165127 abandoned by Reedy:

[mediawiki/skins/Vector@REL1_39] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165127

Change #1165141 had a related patch set uploaded (by Reedy; author: Reedy):

[mediawiki/core@REL1_42] T396685

https://gerrit.wikimedia.org/r/1165141

Change #1165124 merged by jenkins-bot:

[mediawiki/skins/Vector@REL1_44] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165124

Change #1165141 abandoned by Reedy:

[mediawiki/core@REL1_42] T396685

https://gerrit.wikimedia.org/r/1165141

Change #1165126 merged by jenkins-bot:

[mediawiki/skins/Vector@REL1_42] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165126

Change #1165125 merged by jenkins-bot:

[mediawiki/skins/Vector@REL1_43] SECURITY: Insert portlet labels as text instead of HTML

https://gerrit.wikimedia.org/r/1165125

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".
sbassett changed the edit policy from "Custom Policy" to "All Users".
sbassett changed Risk Rating from N/A to Low.
sbassett moved this task from Watching to Our Part Is Done on the Security-Team board.