r40977 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r40976‎ | r40977 | r40978 >
Date:13:01, 18 September 2008
Author:werdna
Status:old
Tags:
Comment:
Add rangeblocks, a bit of a nuclear option for the abuse filter. Not intended for Wikimedia use
Modified paths:
  • /trunk/extensions/AbuseFilter/AbuseFilter.class.php (modified) (history)
  • /trunk/extensions/AbuseFilter/AbuseFilter.i18n.php (modified) (history)
  • /trunk/extensions/AbuseFilter/AbuseFilter.php (modified) (history)
  • /trunk/extensions/AbuseFilter/SpecialAbuseFilter.php (modified) (history)

Diff [purge]

Index: trunk/extensions/AbuseFilter/AbuseFilter.php
@@ -27,10 +27,10 @@
2828 $wgExtensionMessagesFiles['AbuseFilter'] = "$dir/AbuseFilter.i18n.php";
2929 $wgExtensionAliasesFiles['AbuseFilter'] = "$dir/AbuseFilter.alias.php";
3030
31 -$wgAutoloadClasses[ 'AbuseFilter' ] = "$dir/AbuseFilter.class.php";
32 -$wgAutoloadClasses[ 'AbuseFilterParser' ] = "$dir/AbuseFilter.parser.php";
33 -$wgAutoloadClasses[ 'AbuseFilterParserNative' ] = "$dir/AbuseFilter.nativeparser.php";
34 -$wgAutoloadClasses[ 'AbuseFilterHooks' ] = "$dir/AbuseFilter.hooks.php";
 31+$wgAutoloadClasses['AbuseFilter'] = "$dir/AbuseFilter.class.php";
 32+$wgAutoloadClasses['AbuseFilterParser'] = "$dir/AbuseFilter.parser.php";
 33+$wgAutoloadClasses['AbuseFilterParserNative'] = "$dir/AbuseFilter.nativeparser.php";
 34+$wgAutoloadClasses['AbuseFilterHooks'] = "$dir/AbuseFilter.hooks.php";
3535 $wgAutoloadClasses['SpecialAbuseLog'] = "$dir/SpecialAbuseLog.php";
3636 $wgAutoloadClasses['SpecialAbuseFilter'] = "$dir/SpecialAbuseFilter.php";
3737
@@ -50,17 +50,18 @@
5151 $wgAvailableRights[] = 'abusefilter-log';
5252 $wgAvailableRights[] = 'abusefilter-private';
5353
54 -$wgAbuseFilterAvailableActions = array( 'flag', 'throttle', 'warn', 'disallow', 'blockautopromote', 'block', 'degroup' );
 54+$wgAbuseFilterAvailableActions = array( 'flag', 'throttle', 'warn', 'disallow', 'blockautopromote', 'block', 'degroup', 'rangeblock' );
5555
5656 // Conditions take about 4ms to check, so 100 conditions would take 400ms
5757 $wgAbuseFilterConditionLimit = 1000;
5858
59 -// Disable filters if they match more than X edits, constituting more than Y% of the last Z edits
60 -$wgAbuseFilterEmergencyDisableThreshold = 0.05;
61 -$wgAbuseFilterEmergencyDisableCount = 5;
 59+// Disable filters if they match more than X edits, constituting more than Y% of the last Z edits, if they have been changed in the last S seconds
 60+$wgAbuseFilterEmergencyDisableThreshold = 0.50;
 61+$wgAbuseFilterEmergencyDisableCount = 2;
 62+$wgAbuseFilterEmergencyDisableAge = 86400; // One day.
6263
6364 // Abuse filter parser class
64 -$wgAbuseFilterParserClass = 'AbuseFilterParserNative';
 65+$wgAbuseFilterParserClass = 'AbuseFilterParser';
6566 $wgAbuseFilterNativeParser = "$dir/parser_native/af_parser";
6667 $wgAbuseFilterNativeSyntaxCheck = "$dir/parser_native/syntax_check";
6768 $wgAbuseFilterNativeExpressionEvaluator = "$dir/parser_native/af_expr";
Index: trunk/extensions/AbuseFilter/SpecialAbuseFilter.php
@@ -397,7 +397,7 @@
398398 'op-arithmetic' => array('+' => 'addition', '-' => 'subtraction', '*' => 'multiplication', '/' => 'divide', '%' => 'modulo', '**' => 'pow'),
399399 'op-comparison' => array('==' => 'equal', '!=' => 'notequal', '<' => 'lt', '>' => 'gt', '<=' => 'lte', '>=' => 'gte'),
400400 'op-bool' => array( '!' => 'not', '&' => 'and', '|' => 'or', '^' => 'xor' ),
401 - 'misc' => array( 'val1 ? iftrue : iffalse' => 'ternary', 'in' => 'in', 'like' => 'like' ),
 401+ 'misc' => array( 'val1 ? iftrue : iffalse' => 'ternary', 'in' => 'in', 'like' => 'like', '""' => 'stringlit', ),
402402 'funcs' => array( 'length(string)' => 'length', 'lcase(string)' => 'lcase', 'ccnorm(string)' => 'ccnorm', 'rmdoubles(string)' => 'rmdoubles', 'specialratio(string)' => 'specialratio', 'norm(string)' => 'norm', 'count(needle,haystack)' => 'count' ),
403403 'vars' => array( 'ACCOUNTNAME' => 'accountname', 'ACTION' => 'action', 'ADDED_LINES' => 'addedlines', 'EDIT_DELTA' => 'delta', 'EDIT_DIFF' => 'diff', 'NEW_SIZE' => 'newsize', 'OLD_SIZE' => 'oldsize', 'REMOVED_LINES' => 'removedlines', 'SUMMARY' => 'summary', 'ARTICLE_ARTICLEID' => 'article-id', 'ARTICLE_NAMESPACE' => 'article-ns', 'ARTICLE_TEXT' => 'article-text', 'ARTICLE_PREFIXEDTEXT' => 'article-prefixedtext', 'MOVED_FROM_ARTICLEID' => 'movedfrom-id', 'MOVED_FROM_NAMESPACE' => 'movedfrom-ns', 'MOVED_FROM_TEXT' => 'movedfrom-text', 'MOVED_FROM_PREFIXEDTEXT' => 'movedfrom-prefixedtext', 'MOVED_TO_ARTICLEID' => 'movedto-id', 'MOVED_TO_NAMESPACE' => 'movedto-ns', 'MOVED_TO_TEXT' => 'movedto-text', 'MOVED_TO_PREFIXEDTEXT' => 'movedto-prefixedtext', 'USER_EDITCOUNT' => 'user-editcount', 'USER_AGE' => 'user-age', 'USER_NAME' => 'user-name', 'USER_GROUPS' => 'user-groups', 'USER_EMAILCONFIRM' => 'user-emailconfirm'),
404404 );
Index: trunk/extensions/AbuseFilter/AbuseFilter.class.php
@@ -9,6 +9,7 @@
1010 public static $modifyCache = array();
1111 public static $condLimitEnabled = true;
1212 public static $condCount = 0;
 13+ public static $filters = array();
1314
1415 public static function generateUserVars( $user ) {
1516 $vars = array();
@@ -130,6 +131,7 @@
131132 $filter_matched = array();
132133
133134 while ( $row = $dbr->fetchObject( $res ) ) {
 135+ self::$filters[$row->af_id] = $row;
134136 if ( self::checkConditions( $row->af_pattern, $vars ) ) {
135137 $blocking_filters[$row->af_id] = $row;
136138
@@ -219,7 +221,7 @@
220222 case 'warn':
221223 wfLoadExtensionMessages( 'AbuseFilter' );
222224
223 - if (!$_SESSION['abusefilter-warned']) {
 225+ if (!isset($_SESSION['abusefilter-warned']) || !$_SESSION['abusefilter-warned']) {
224226 $_SESSION['abusefilter-warned'] = true;
225227
226228 // Threaten them a little bit
@@ -259,12 +261,11 @@
260262 $block = new Block;
261263 $block->mAddress = $wgUser->getName();
262264 $block->mUser = $wgUser->getId();
263 - $block->mBy = User::idFromName( wfMsgForContent( 'abusefilter-blocker' ) ); // Let's say the site owner blocked them
264 - $block->mByName = wfMsgForContent( 'abusefilter-blocker' );
 265+ $block->mBy = $filterUser->getId();
 266+ $block->mByName = $filterUser->getName();
265267 $block->mReason = wfMsgForContent( 'abusefilter-blockreason', $rule_desc );
266268 $block->mTimestamp = wfTimestampNow();
267 - $block->mEnableAutoblock = 1;
268 - $block->mAngryAutoblock = 1; // Block lots of IPs
 269+ $block->mAnonOnly = 1;
269270 $block->mCreateAccount = 1;
270271 $block->mExpiry = 'infinity';
271272
@@ -282,6 +283,47 @@
283284
284285 $display .= wfMsgNoTrans( 'abusefilter-blocked-display', $rule_desc ) ."<br />\n";
285286 break;
 287+ case 'rangeblock':
 288+ wfLoadExtensionMessages( 'AbuseFilter' );
 289+
 290+ global $wgUser;
 291+ $filterUser = AbuseFilter::getFilterUser();
 292+
 293+ $range = IP::toHex( wfGetIP() );
 294+ $range = substr( $range, 0, 4 ) . '0000';
 295+ $range = long2ip( hexdec( $range ) );
 296+ $range .= "/16";
 297+ $range = Block::normaliseRange( $range );
 298+
 299+ // Create a block.
 300+ $block = new Block;
 301+ $block->mAddress = $range;
 302+ $block->mUser = 0;
 303+ $block->mBy = $filterUser->getId();
 304+ $block->mByName = $filterUser->getName();
 305+ $block->mReason = wfMsgForContent( 'abusefilter-blockreason', $rule_desc );
 306+ $block->mTimestamp = wfTimestampNow();
 307+ $block->mAnonOnly = 0;
 308+ $block->mCreateAccount = 1;
 309+ $block->mExpiry = Block::parseExpiryInput( '1 week' );
 310+
 311+ $block->initialiseRange();
 312+
 313+ $block->insert();
 314+
 315+ // Log it
 316+ # Prepare log parameters
 317+ $logParams = array();
 318+ $logParams[] = 'indefinite';
 319+ $logParams[] = 'nocreate, angry-autoblock';
 320+
 321+ $log = new LogPage( 'block' );
 322+ $log->addEntry( 'block', SpecialPage::getTitleFor( 'Contributions', $range ),
 323+ wfMsgForContent( 'abusefilter-blockreason', $rule_desc ), $logParams, self::getFilterUser() );
 324+
 325+ $display .= wfMsgNoTrans( 'abusefilter-blocked-display', $rule_desc ) ."<br />\n";
 326+ break;
 327+
286328 case 'throttle':
287329 $throttleId = array_shift( $parameters );
288330 list( $rateCount, $ratePeriod ) = explode( ',', array_shift( $parameters ) );
@@ -466,7 +508,7 @@
467509
468510 $anyMatch = false;
469511
470 - global $wgAbuseFilterEmergencyDisableThreshold, $wgAbuseFilterEmergencyDisableCount;
 512+ global $wgAbuseFilterEmergencyDisableThreshold, $wgAbuseFilterEmergencyDisableCount, $wgAbuseFilterEmergencyDisableAge;
471513
472514 foreach( $filters as $filter => $matched ) {
473515 if ($matched) {
@@ -479,7 +521,10 @@
480522 $wgMemc->set( self::filterMatchesKey( $filter ), 1, self::$statsStoragePeriod );
481523 }
482524
483 - if ($match_count > $wgAbuseFilterEmergencyDisableCount && ($match_count / $total) > $wgAbuseFilterEmergencyDisableThreshold) {
 525+ $filter_age = wfTimestamp( TS_UNIX, self::$filters[$filter]['af_timestamp'] );
 526+ $throttle_exempt_time = $filter_age + $wgAbuseFilterEmergencyDisableAge;
 527+
 528+ if ($throttle_exempt_time > time() && $match_count > $wgAbuseFilterEmergencyDisableCount && ($match_count / $total) > $wgAbuseFilterEmergencyDisableThreshold) {
484529 // More than X matches, constituting more than Y% of last Z edits. Disable it.
485530 $dbw = wfGetDB( DB_MASTER );
486531 $dbw->update( 'abuse_filter', array( 'af_enabled' => 0, 'af_throttled' => 1 ), array( 'af_id' => $filter ), __METHOD__ );
Index: trunk/extensions/AbuseFilter/AbuseFilter.i18n.php
@@ -42,7 +42,7 @@
4343 A brief description of the abuse rule which your action matched is: $1",
4444
4545 'abusefilter-blocker' => 'Abuse filter',
46 - 'abusefilter-blockreason' => 'Automatically blocked by abuse filter. Rule description: $1',
 46+ 'abusefilter-blockreason' => 'Automatically blocked by abuse filter. Description of matched rule: $1',
4747 'abusefilter-degroupreason' => 'Rights automatically stripped by abuse filter. Rule description: $1',
4848
4949 'abusefilter-accountreserved' => 'This account name is reserved for use by the abuse filter.',
@@ -133,6 +133,7 @@
134134 'abusefilter-edit-action-degroup' => 'Remove the user from all privileged groups',
135135 'abusefilter-edit-action-block' => 'Block the user and/or IP address from editing',
136136 'abusefilter-edit-action-throttle' => 'Trigger actions only if the user trips a rate limit',
 137+ 'abusefilter-edit-action-rangeblock' => 'Block the /16 range from which the user originates.',
137138 'abusefilter-edit-throttle-count' => 'Number of actions to allow:',
138139 'abusefilter-edit-throttle-period' => 'Period of time:',
139140 'abusefilter-edit-throttle-seconds' => '$1 {{PLURAL:$1|second|seconds}}',
@@ -171,6 +172,7 @@
172173 'abusefilter-edit-builder-misc-ternary' => 'Ternary operator (1 ? 2 : 3)',
173174 'abusefilter-edit-builder-misc-in' => 'contained in string (in)',
174175 'abusefilter-edit-builder-misc-like' => 'Matches regex (like)',
 176+ 'abusefilter-edit-builder-misc-stringlit' => 'String literal ("")',
175177 'abusefilter-edit-builder-group-funcs' => 'Functions',
176178 'abusefilter-edit-builder-funcs-length' => 'String length (length)',
177179 'abusefilter-edit-builder-funcs-lcase' => 'To lower case (lcase)',

Follow-up revisions

RevisionCommit summaryAuthorDate
r47046(bug 7509) Separation strings should be configurable...siebrand17:48, 9 February 2009