Page MenuHomePhabricator

Allow Stewards to enable 'emergency CAPTCHAs' for anonymous IP edits
Open, MediumPublic

Description

In the recent botnet editing attack, one of the original reasons that the wiki community escalated to SRE was that enabling the 'emergency CAPTCHA' functionality for anonymous IP edits requires a configuration push.

Currently this is implemented by editing $wmgEmergencyCaptcha in InitialiseSettings.php, like this patch.

There was broad agreement afterwards from both involved WMF staff and from responders in the community that it would be ideal if Stewards could enable this themselves, without having to escalate to someone with deploy access.

Event Timeline

Shame this couldn't really use an opt-in wiki set—that kind of functionality would be great though 😁

Shame this couldn't really use an opt-in wiki set—that kind of functionality would be great though 😁

Why couldn't it?

$emergencyCaptchaWikiSet = \MediaWiki\Extension\CentralAuth\WikiSet::newFromName( 'emergency-captcha-wikis' );
if ( $emergencyCaptchaWikiSet !== null ) {
	$wikisToEnable = $emergencyCaptchaWikiSet->getWikis();
	foreach ( $wikisToEnable as $wiki ) {
		$wmgEmergencyCaptcha[$wiki] = true;
	}
	unset( $wikisToEnable );
	unset( $wiki );
}
unset( $emergenceyCaptchaWikiSet );

any time a wikiset is defined with the name 'emergency-captcha-wikis', whether it is opt-in or opt-out, if this is added to CommonSettings.php it will turn on emergency captcha on those wikis. It should be fairly performant, since the wiki sets are cached indefinitely and only purged when they change

Shame this couldn't really use an opt-in wiki set—that kind of functionality would be great though 😁

Why couldn't it?

I'm not sure if I like a pattern of wiki sets with "magical" properties not configured via or visible in the UI.

$emergencyCaptchaWikiSet = \MediaWiki\Extension\CentralAuth\WikiSet::newFromName( 'emergency-captcha-wikis' );
if ( $emergencyCaptchaWikiSet !== null ) {
	$wikisToEnable = $emergencyCaptchaWikiSet->getWikis();
	foreach ( $wikisToEnable as $wiki ) {
		$wmgEmergencyCaptcha[$wiki] = true;
	}
	unset( $wikisToEnable );
	unset( $wiki );
}
unset( $emergenceyCaptchaWikiSet );

any time a wikiset is defined with the name 'emergency-captcha-wikis', whether it is opt-in or opt-out, if this is added to CommonSettings.php it will turn on emergency captcha on those wikis. It should be fairly performant, since the wiki sets are cached indefinitely and only purged when they change

CR-1 as too complicated:

if (
	$wmgEnableEmergencyCaptcha
	// if we're hardcoding things, I'd prefer hardcoding an ID instead of a name since it's harder to change by accident
	|| \MediaWiki\Extension\CentralAuth\WikiSet::newFromId( 42 )->inSet( WikiMap::getCurrentWikiId() )
) {
	// do what's currently in the `if ( $wmgEnableEmergencyCaptcha )` block
}

Although I'm not sure if you can access the database or caches when evaluating CS.php since the settings needed for that aren't fully registered yet.

A better solution would be to add a hook to ConfirmEdit that lets you specify if a given action should get a captcha prompt, at that point the config is surely fully loaded and it's also more efficient (less queries needed even for the cached values, since you don't need to evaluate that every page view).

The problem with using a hard coded id is that as far as I understand it, when all wikis are removed from a set it gets deleted, and the next time we want to use it a new set would be created with a different id, so this would require the same set to keep existing. On the other hand, doing it by name is just as unique but allows for recreation

(I'd like to note that the permissions for this task do not allow the subscribers to view it. Does it even need to be private, anyway?)

sbassett subscribed.

(I'd like to note that the permissions for this task do not allow the subscribers to view it. Does it even need to be private, anyway?)

Maybe due to it being sub-tasked from T302047? I don't think this needs to be private at all, so I'll go ahead and make it public.

sbassett changed the visibility from "Custom Policy" to "Public (No Login Required)".Mar 9 2022, 10:22 PM
sbassett changed the edit policy from "Custom Policy" to "All Users".

Given

... it would be ideal if Stewards could enable this themselves, without having to escalate to someone with deploy access.

This task is still about some kind of manual UI config mechanism, no? Like a new ConfirmEdit special page or a lightweight extension under metawiki that allowed for an easy way to set/unset $wmgEnableEmergencyCaptcha for various projects or groups of projects?

Given

... it would be ideal if Stewards could enable this themselves, without having to escalate to someone with deploy access.

This task is still about some kind of manual UI config mechanism, no? Like a new ConfirmEdit special page or a lightweight extension under metawiki that allowed for an easy way to set/unset $wmgEnableEmergencyCaptcha for various projects or groups of projects?

So the reason I suggested using CentralAuth global groups is that if we want to add new functionality like this somewhere else, it requires some thinking about how we should be storing the data - should there be a new database table to remember which wikis are configured to have it enabled? Easier to implement, but means a database read each time. Or, perhaps have the special page or whatever write to an included php file, like the installer does when setting the initial configuration - harder to implement, but lower performance impact since the settings would just be read as normal configuration.

Reusing CentralAuth means that there is already an interface, logging, database, etc. available, which I think would be easier and more stable than trying to write new handling from scratch.

jbond triaged this task as Medium priority.Mar 21 2022, 11:41 AM

Change 778678 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/extensions/ConfirmEdit@master] Add new ConfirmEditTriggersCaptchaHook

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

Change 778680 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/extensions/CentralAuth@master] Allow stewards to enable emergency captchas via a wikiset

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

Change 778678 merged by jenkins-bot:

[mediawiki/extensions/ConfirmEdit@master] Add new ConfirmEditTriggersCaptchaHook

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

Change 778680 abandoned by Zabe:

[mediawiki/extensions/CentralAuth@master] WIP: Allow stewards to enable emergency captchas via a wikiset

Reason:

Implementing emergency captchas through ca wikisets feels very hacky and it doesn't really bring a lot of benefits.

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

Change 814357 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/extensions/EmergencyCaptcha@master] Initial commit

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

I'm not sure if I like a pattern of wiki sets with "magical" properties not configured via or visible in the UI.

I need to agree with this.

Given

... it would be ideal if Stewards could enable this themselves, without having to escalate to someone with deploy access.

This task is still about some kind of manual UI config mechanism, no? Like a new ConfirmEdit special page or a lightweight extension under metawiki that allowed for an easy way to set/unset $wmgEnableEmergencyCaptcha for various projects or groups of projects?

So the reason I suggested using CentralAuth global groups is that if we want to add new functionality like this somewhere else, it requires some thinking about how we should be storing the data - should there be a new database table to remember which wikis are configured to have it enabled? Easier to implement, but means a database read each time. Or, perhaps have the special page or whatever write to an included php file, like the installer does when setting the initial configuration - harder to implement, but lower performance impact since the settings would just be read as normal configuration.

Reusing CentralAuth means that there is already an interface, logging, database, etc. available, which I think would be easier and more stable than trying to write new handling from scratch.

I have tried this a bit and the amount that can be reused is limited. And the work you need to invest to make this not some kind of "magical" property is also quite a bit, since you need to write some sort of UI for this and you also need to make the wikiset logs for this understandable. Implementing emergency captchas this way feels really hacky and I don't really like it. I prefer putting this into a "micro-extension". The database and logging needed for this is actually quite basic.

Change 818270 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/extensions/ConfirmEdit@master] Run ConfirmEditTriggersCaptchaHook under correct name

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

Change 818270 merged by jenkins-bot:

[mediawiki/extensions/ConfirmEdit@master] Run ConfirmEditTriggersCaptchaHook under correct name

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

akosiaris subscribed.

I am tentatively just removing SRE as I don't see something specifically actionable for SRE right now. Feel free to re-add.

Perhaps this good be a good Community Configuration candidate @KStoller-WMF?

The current emergency captchas are really an 'break glass in case of fire' style solution due to their various accessibility problems. So I'd much rather see time spent into either building better anti-abuse tools that make them not required or a more general solution for moving certain configuration from mediawiki-config.git to something that the community can self-manage, rather than building something specific for enabling the captchas only.

The current emergency captchas are really an 'break glass in case of fire' style solution due to their various accessibility problems. So I'd much rather see time spent into either building better anti-abuse tools that make them not required or a more general solution for moving certain configuration from mediawiki-config.git to something that the community can self-manage, rather than building something specific for enabling the captchas only.

Definitely, that's work already underway, T323811: [EPIC] Community configuration 2.0: Factor Community configuration out of GrowthExperiments, which is what Sam means by Community Configuration. Moving more general parts of AF configuration into that system ahead of, or at least at the same as, the emergency-CAPTCHA preference would, I agree, be better for both moderating and moderated users' experience.

This is all great long-term planning (seriously!) but is there a chance of making a stopgap, light-weight solution for just EmergencyCaptcha? Even if it's as simple as, I don't know, a page editable only by stewards (a few ways to implement that) that allows for a comma-separated list of wikis to have EmergencyCaptcha on on; have a script check it every 5 minutes or something. (Probably not ideal implementation, but just giving an idea of a fairly cheap implementation.)

This is all great long-term planning (seriously!) but is there a chance of making a stopgap, light-weight solution for just EmergencyCaptcha? Even if it's as simple as, I don't know, a page editable only by stewards (a few ways to implement that) that allows for a comma-separated list of wikis to have EmergencyCaptcha on on; have a script check it every 5 minutes or something. (Probably not ideal implementation, but just giving an idea of a fairly cheap implementation.)

I think @Zabe's WIP approach above (https://gerrit.wikimedia.org/r/814357) of creating a new EmergencyCaptcha extension is probably the fastest track for a more immediate, light-weight solution.

Zabe removed Zabe as the assignee of this task.Aug 2 2023, 4:45 PM

I don't have the time to work on it at the moment, feel free to adopt my patch or not if you prefer a different solution. :)

Change 814357 abandoned by Zabe:

[mediawiki/extensions/EmergencyCaptcha@master] Initial commit

Reason:

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