Page MenuHomePhabricator

DiscussionTools' maintenance scripts cannot be executed in Wikimedia production
Closed, ResolvedPublic

Description

During today (2022-09-28) UTC afternoon B&C backport window, @taavi tried to run extensions/DiscussionTools/maintenance/persistRevisionThreadItems.php for testwiki.

Output
taavi@mwmaint1002:~$ time mwscript extensions/DiscussionTools/maintenance/persistRevisionThreadItems.php --wiki=testwiki --current --all | tee persistRevisionThreadItems.log
Bad MediaWiki install path: /srv/mediawiki/php-1.39.0-wmf.26

This is caused by a check in the script itself, which requires that MW_INSTALL_PATH may not contain dots. According to @matmarex, this was added following Security-Team's recommendation (discussion is at T242134, patch).

The check makes it impossible to run the script in Wikimedia production, because the installation patch in WMF production is /srv/mediawiki/php-1.39.0-wmf.26 (and includes a couple of dots).

I have two possible solutions here:

  1. Remove the mitigation entirely. Personally, I don't think it serves any meaningful purpose. If an attacker is in a position where they can control the content of MW_INSTALL_PATH (to get the two dots there in the first place), they are also very likely in a position where they can set the variable to an arbitrary string, rendering the protection ineffective. In theory, dots can be abused if an attacker has append-only write access to MW_INSTALL_PATH (instead of having the ability to point the variable to subdirs of what it was before, they'd have the ability to point it to an arbitrary directory). The second prohibited character, ~, has no special meaning in PHP at all (tilde expansion is a shell feature, and even there it is only valid at the start of the path => an attacker would have to be able to set MW_INSTALL_PATH to an arbitrary path already anyway).
  2. Replace the dot with two dots, as two dots is the special-meaning directory we're apparently concerned about here.

Regardless of the solution we decide to go with, it should be unified across all extensions (or at least the ones we have deployed on our own servers).

Event Timeline

Urbanecm renamed this task from DiscussionTools' maintenance script cannot be executed in Wikimedia production to DiscussionTools' maintenance scripts cannot be executed in Wikimedia production.Aug 29 2022, 2:05 PM

Change 827501 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@master] Fix boilerplate in maintenance scripts for WMF production

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

The check makes it impossible to run the script in Wikimedia production, because the installation patch in WMF production is /srv/mediawiki/php-1.39.0-wmf.26 (and includes a couple of dots).

As a horrible hack, you could just run the script in its symlink'ed position of /srv/mediawiki/php/… (though of course we should fix this more generally).

Change 827501 merged by jenkins-bot:

[mediawiki/extensions/DiscussionTools@master] Fix boilerplate in maintenance scripts for WMF production

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

Change 827202 had a related patch set uploaded (by Bartosz Dziewoński; author: Bartosz Dziewoński):

[mediawiki/extensions/DiscussionTools@wmf/1.39.0-wmf.26] Fix boilerplate in maintenance scripts for WMF production

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

Change 827202 merged by jenkins-bot:

[mediawiki/extensions/DiscussionTools@wmf/1.39.0-wmf.26] Fix boilerplate in maintenance scripts for WMF production

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

Mentioned in SAL (#wikimedia-operations) [2022-08-29T20:27:06Z] <cjming@deploy1002> sync-file aborted: Backport: [[gerrit:827202|Fix boilerplate in maintenance scripts for WMF production (T316548)]] (duration: 00m 05s)

Mentioned in SAL (#wikimedia-operations) [2022-08-29T20:31:01Z] <cjming@deploy1002> Synchronized php-1.39.0-wmf.26/extensions/DiscussionTools/maintenance: Backport: [[gerrit:827202|Fix boilerplate in maintenance scripts for WMF production (T316548)]] (duration: 03m 41s)

I have two possible solutions here:

  1. Remove the mitigation entirely. Personally, I don't think it serves any meaningful purpose. If an attacker is in a position where they can control the content of MW_INSTALL_PATH (to get the two dots there in the first place), they are also very likely in a position where they can set the variable to an arbitrary string, rendering the protection ineffective. In theory, dots can be abused if an attacker has append-only write access to MW_INSTALL_PATH (instead of having the ability to point the variable to subdirs of what it was before, they'd have the ability to point it to an arbitrary directory). The second prohibited character, ~, has no special meaning in PHP at all (tilde expansion is a shell feature, and even there it is only valid at the start of the path => an attacker would have to be able to set MW_INSTALL_PATH to an arbitrary path already anyway).
  2. Replace the dot with two dots, as two dots is the special-meaning directory we're apparently concerned about here.

Regardless of the solution we decide to go with, it should be unified across all extensions (or at least the ones we have deployed on our own servers).

My patch, which I wrote before reading this, does a minimal version of option 1 – it just removes the check for the dot.

Scripts in other extensions where the same pattern has been copy-pasted (https://codesearch.wmcloud.org/search/?q=strpos%5C(%20%5C%24basePath%2C%20%27%5C.%27%20%5C)%20!%3D%3D%20false) aren't actually intended to be run in production, they're all scripts for developers (to update vendored JS code dependencies). I'm not sure if it's worth the effort to change them.

In the long term, I think the fix for this is to improve how maintenance scripts work, so that they can use autoloader and not have to manually build paths and require them – and it turns out that work on this is ongoing in T99268: RfC: Create a proper command-line runner for MediaWiki maintenance tasks.

Thanks all for dealing with this bug. As I noted on the review task, the underlying issue was deemed low risk and per the current risk management framework, this risk category is automatically accepted by the WMF and no additional action is required related to the removal of related mitigations.