Page MenuHomeMiraheze

Automatically flag problematic block reasons to Trust and Safety
Closed, ResolvedPublic

Description

There is a history of users being blocked for illegal activities or being underage and those reports not making themselves through to Trust and Safety either for a few weeks, if ever (there's probably a few we still aren't aware of now!).

This was actually originally a suggestion of @Agent_Isai and I think we should work towards making this a reality, to automatically scan new blocks as they are made and come up with a list of possible things Trust and Safety should look into more and then integrate into TSPortal to automatically file reports/DPAs to put these on our radar immediately.

Possible Block Reasons

  • 'underage'
  • 'death threats'
  • ...

Event Timeline

Owen triaged this task as Low priority.Jul 17 2022, 15:26
Owen created this task.

I would think maybe this could be integrated with AbuseFilter somehow or maybe the IRC feeds (though those don't cover private wikis)

Unknown Object (User) moved this task from Backlog to MediaWiki on the Goal-2022-Jul-Dec board.Sep 12 2022, 22:17
Unknown Object (User) moved this task from Backlog to Long Term on the MediaWiki (SRE) board.
Unknown Object (User) moved this task from Long Term to Goals on the MediaWiki (SRE) board.

I don't think AbuseFilter can trigger on blocks, scanning IRC feeds is more feasible for this. As they follow a standardized format (<databasename> * [[Special:Log/block]] block * <blockingadmin> * blocked [[User:<blockeduser>]] with an expiration time of <expirationtime> (<blockparameters>): <reason>), you could have an IRC bot listening on #miraheze-feed scanning for block messages, extract the reason, use regex to look for keywords in the block reason (like those given by Owen), then flag them for review at TSPortal if the regex matches.

This should be implemented via a Hook not via IRC scanning as private wikis aren't on IRC.

https://github.com/wikimedia/mediawiki/blob/master/includes/specials/Hook/BlockIpCompleteHook.php

This comment was removed by OrangeStar.

Nevermind my previous comment, it had a mistake, gimme a second

This could be done by using $wgHooks then, or perhaps a fancy extension that has a special page that allows modifying the list of keywords on-wiki, if you really want to.

Anyway, I quickly hacked up a $wgHooks version, completely untested and dirty code though, should be good to test the idea out before developing more heavy stuff like extensions, if T&S ever decides to go that route.

use MediaWiki\Http\HttpRequestFactory;

$wi = new MirahezeFunctions();
$efTSPortalWriteKey = 'PutTheWriteKeyHere';
$efTSPortalUrl = 'https://reports.miraheze.org'
$efTSPortalUsername = 'MediaWiki-BlockAlert';
$efBlockKeywordsArray = ['underage', 'death threats'];

function efBlockKeywords($block, $user, $priorblock) {
	//https://doc.wikimedia.org/mediawiki-core/master/php/classMediaWiki_1_1Block_1_1DatabaseBlock.html
	foreach ($efBlockKeywordsArray as $needle) {
		if (strpos($block->getReason(), $needle) !== false) { //str_contains in PHP8, getReason is deprecated
			//https://doc.wikimedia.org/mediawiki-core/master/php/classMediaWiki_1_1Http_1_1HttpRequestFactory.html
			$TSPortalPostData = ["writekey" => $efTSPortalWriteKey, "subjectuser" => "BlockAlert-dummy", type => "people-other", "reportinguser" => $efTSPortalUsername, "text" => "This is an automatic report by BlockAlert. An user was blocked at " . $wi->dbname . ", and the block contains a keyword. The block ID at the wiki is " . $block->getId() . ", and the block reason is: " . $block->getReason()];
			httprequest = new HttpRequestFactory();
			httprequest->post($efTSPortalUrl . '/api/report', ["postData" => $TSPortalPostData]);
		};
	};
};

$wgHooks['BlockIpComplete'][] = 'efBlockKeywords';

I've been reading the documentation of DatabaseBlock, and as far as I understand it, there's no way to get the username of the blocked user, only the username of the admin. You're supposed to use the ID of the blocked user to query the database and retrieve the username, apparently.

Also, this would need to import whatever script Miraheze has that defines the MirahezeFunctions() function, as that's what this uses to get the database name of the wiki where the block happened.

It should be put on a file that isn't public, unless you want to reveal the writekey to the world.

Unknown Object (User) added a comment.EditedDec 19 2022, 00:23

@OrangeStar it should be done using https://github.com/miraheze/MirahezeMagic/tree/master/includes/MirahezeMagicHooks.php, or similar, using $wmgTSPortalWriteKey for the write key, as we can add that to PrivateSettings.php. Database can be retrieved with global configuration variable, DBname in MirahezeMagicHooks also. But that is very helpful of you to put that draft together. Thank you very much for that. I can probably turn that into something usable at some point now.

Unknown Object (User) added a comment.EditedDec 19 2022, 00:45

So something like this in MirahezeMagicHooks:

public static function onBlockIpComplete( $block, $user, $priorBlock ) {
	$config = MediaWikiServices::getInstance()->getConfigFactory()->makeConfig( 'mirahezemagic' );

	$reportsUsername = $config->get( 'MirahezeReportsBlockAlertUsername' );
	$reportsBlockAlertKeywords = $config->get( 'MirahezeReportsBlockAlertKeywords' );

	foreach ( $reportsBlockAlertKeywords as $keyword ) {
		if ( str_contains( $block->getReasonComment()->text, $keyword ) ) {
			$reportsPostData = [
				'writekey' => $config->get( 'MirahezeReportsWriteKey' ),
				'subjectuser' => $block->getTargetName(),
				'type' => 'people-other',
				'reportinguser' => $reportsUsername,
				'text' => 'This is an automatic report by BlockAlert. A user was blocked on ' . $config->get( 'DBname' ) . ', and the block matched keyword "' . $keyword . '." The block ID at the wiki is ' . $block->getId() . ', and the block reason is: ' . $block->getReasonComment()->text
			];
			$httpRequestFactory = MediaWikiServices::getInstance()->getHttpRequestFactory();
			$httpRequestFactory->post( 'https://reports.miraheze.org/api/report', [ 'postData' => $reportsPostData ] );
		}
	}
}

Again, that is untested, I didn't even look at code, just modified to adjust for usage in MirahezeMagicHooks.

That looks like real production code now. I also see you found a way to get the username of the blocked user, nice.

edit: I see I used the PHP variable names as parameters instead of the POST parameters TSPortal was looking for, big oops.

Unknown Object (User) claimed this task.Dec 19 2022, 16:37

That looks like real production code now. I also see you found a way to get the username of the blocked user, nice.

edit: I see I used the PHP variable names as parameters instead of the POST parameters TSPortal was looking for, big oops.

Yep, no problem though. Your help here was greatly appreciated, and pushed this task forward. I have now tested it and it fully works. Your help was greatly appreciated.

Unknown Object (User) moved this task from Unsorted to Goals on the Universal Omega board.Dec 19 2022, 16:37
Unknown Object (User) closed this task as Resolved.Dec 21 2022, 18:43

This is now done. Just needs configured (https://github.com/miraheze/mw-config/pull/5036) now.