Пример #1
0
 /**
  * Test for IP::sanitizeRange()
  * @dataProvider provideIPCIDRs
  */
 function testSanitizeRange($input, $expected, $description)
 {
     $this->assertEquals($expected, IP::sanitizeRange($input), $description);
 }
 /**
  * @param $action string
  * @param $parameters array
  * @param $title Title
  * @param $vars AbuseFilterVariableHolder
  * @param $rule_desc
  * @param $rule_number int|string
  *
  * @return array|null a message describing the action that was taken,
  *         or null if no action was taken. The message is given as an array
  *         containing the message key followed by any message parameters.
  *
  * @note: Returning the message as an array instead of a Message object is
  *        needed for compatibility with MW 1.20: we will be constructing a
  *        Status object from these messages, and before 1.21, Status did
  *        not accept Message objects to be added directly.
  */
 public static function takeConsequenceAction($action, $parameters, $title, $vars, $rule_desc, $rule_number)
 {
     global $wgAbuseFilterCustomActionsHandlers, $wgRequest;
     $message = null;
     switch ($action) {
         case 'disallow':
             if (strlen($parameters[0])) {
                 $message = array($parameters[0], $rule_desc, $rule_number);
             } else {
                 // Generic message.
                 $message = array('abusefilter-disallowed', $rule_desc, $rule_number);
             }
             break;
         case 'block':
             global $wgUser, $wgAbuseFilterBlockDuration, $wgAbuseFilterAnonBlockDuration;
             $filterUser = AbuseFilter::getFilterUser();
             // Create a block.
             $block = new Block();
             $block->setTarget($wgUser->getName());
             $block->setBlocker($filterUser);
             $block->mReason = wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text();
             $block->isHardblock(false);
             $block->isAutoblocking(true);
             $block->prevents('createaccount', true);
             $block->prevents('editownusertalk', false);
             if ($wgUser->isAnon() && $wgAbuseFilterAnonBlockDuration !== null) {
                 // The user isn't logged in and the anon block duration doesn't default to $wgAbuseFilterBlockDuration
                 $expiry = $wgAbuseFilterAnonBlockDuration;
             } else {
                 $expiry = $wgAbuseFilterBlockDuration;
             }
             $block->mExpiry = SpecialBlock::parseExpiryInput($expiry);
             $block->insert();
             // Log it
             # Prepare log parameters
             $logParams = array();
             if ($block->mExpiry == 'infinity') {
                 $logParams[] = 'indefinite';
             } else {
                 $logParams[] = $expiry;
             }
             $logParams[] = 'nocreate';
             $log = new LogPage('block');
             $log->addEntry('block', Title::makeTitle(NS_USER, $wgUser->getName()), wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(), $logParams, self::getFilterUser());
             $message = array('abusefilter-blocked-display', $rule_desc, $rule_number);
             break;
         case 'rangeblock':
             $filterUser = AbuseFilter::getFilterUser();
             $range = IP::sanitizeRange($wgRequest->getIP() . '/16');
             // Create a block.
             $block = new Block();
             $block->setTarget($range);
             $block->setBlocker($filterUser);
             $block->mReason = wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text();
             $block->isHardblock(false);
             $block->prevents('createaccount', true);
             $block->prevents('editownusertalk', false);
             $block->mExpiry = SpecialBlock::parseExpiryInput('1 week');
             $block->insert();
             // Log it
             # Prepare log parameters
             $logParams = array();
             $logParams[] = 'indefinite';
             $logParams[] = 'nocreate';
             $log = new LogPage('block');
             $log->addEntry('block', Title::makeTitle(NS_USER, $range), wfMessage('abusefilter-blockreason', $rule_desc, $rule_number)->inContentLanguage()->text(), $logParams, self::getFilterUser());
             $message = array('abusefilter-blocked-display', $rule_desc, $rule_number);
             break;
         case 'degroup':
             global $wgUser;
             if (!$wgUser->isAnon()) {
                 // Remove all groups from the user. Ouch.
                 $groups = $wgUser->getGroups();
                 foreach ($groups as $group) {
                     $wgUser->removeGroup($group);
                 }
                 $message = array('abusefilter-degrouped', $rule_desc, $rule_number);
                 // Don't log it if there aren't any groups being removed!
                 if (!count($groups)) {
                     break;
                 }
                 // Log it.
                 $log = new LogPage('rights');
                 $log->addEntry('rights', $wgUser->getUserPage(), wfMessage('abusefilter-degroupreason', $rule_desc, $rule_number)->inContentLanguage()->text(), array(implode(', ', $groups), ''), self::getFilterUser());
             }
             break;
         case 'blockautopromote':
             global $wgUser, $wgMemc;
             if (!$wgUser->isAnon()) {
                 $blockPeriod = (int) mt_rand(3 * 86400, 7 * 86400);
                 // Block for 3-7 days.
                 $wgMemc->set(self::autoPromoteBlockKey($wgUser), true, $blockPeriod);
                 $message = array('abusefilter-autopromote-blocked', $rule_desc, $rule_number);
             }
             break;
         case 'flag':
             // Do nothing. Here for completeness.
             break;
         case 'tag':
             // Mark with a tag on recentchanges.
             global $wgUser;
             $actionID = implode('-', array($title->getPrefixedText(), $wgUser->getName(), $vars->getVar('ACTION')->toString()));
             if (!isset(AbuseFilter::$tagsToSet[$actionID])) {
                 AbuseFilter::$tagsToSet[$actionID] = $parameters;
             } else {
                 AbuseFilter::$tagsToSet[$actionID] = array_merge(AbuseFilter::$tagsToSet[$actionID], $parameters);
             }
             break;
         default:
             if (isset($wgAbuseFilterCustomActionsHandlers[$action])) {
                 $custom_function = $wgAbuseFilterCustomActionsHandlers[$action];
                 if (is_callable($custom_function)) {
                     $msg = call_user_func($custom_function, $action, $parameters, $title, $vars, $rule_desc, $rule_number);
                 }
                 if (isset($msg)) {
                     $message = array($msg);
                 }
             } else {
                 wfDebugLog('AbuseFilter', "Unrecognised action {$action}");
             }
     }
     return $message;
 }
 protected function addXffBlocks()
 {
     static $inited = false;
     if ($inited) {
         return;
     }
     $inited = true;
     $blockList = array(array('target' => '70.2.0.0/16', 'type' => Block::TYPE_RANGE, 'desc' => 'Range Hardblock', 'ACDisable' => false, 'isHardblock' => true, 'isAutoBlocking' => false), array('target' => '2001:4860:4001::/48', 'type' => Block::TYPE_RANGE, 'desc' => 'Range6 Hardblock', 'ACDisable' => false, 'isHardblock' => true, 'isAutoBlocking' => false), array('target' => '60.2.0.0/16', 'type' => Block::TYPE_RANGE, 'desc' => 'Range Softblock with AC Disabled', 'ACDisable' => true, 'isHardblock' => false, 'isAutoBlocking' => false), array('target' => '50.2.0.0/16', 'type' => Block::TYPE_RANGE, 'desc' => 'Range Softblock', 'ACDisable' => false, 'isHardblock' => false, 'isAutoBlocking' => false), array('target' => '50.1.1.1', 'type' => Block::TYPE_IP, 'desc' => 'Exact Softblock', 'ACDisable' => false, 'isHardblock' => false, 'isAutoBlocking' => false));
     foreach ($blockList as $insBlock) {
         $target = $insBlock['target'];
         if ($insBlock['type'] === Block::TYPE_IP) {
             $target = User::newFromName(IP::sanitizeIP($target), false)->getName();
         } elseif ($insBlock['type'] === Block::TYPE_RANGE) {
             $target = IP::sanitizeRange($target);
         }
         $block = new Block();
         $block->setTarget($target);
         $block->setBlocker('testblocker@global');
         $block->mReason = $insBlock['desc'];
         $block->mExpiry = 'infinity';
         $block->prevents('createaccount', $insBlock['ACDisable']);
         $block->isHardblock($insBlock['isHardblock']);
         $block->isAutoblocking($insBlock['isAutoBlocking']);
         $block->insert();
     }
 }
Пример #4
0
 /**
  * From an existing Block, get the target and the type of target.
  * Note that, except for null, it is always safe to treat the target
  * as a string; for User objects this will return User::__toString()
  * which in turn gives User::getName().
  *
  * @param string|int|User|null $target
  * @return array( User|String|null, Block::TYPE_ constant|null )
  */
 public static function parseTarget($target)
 {
     # We may have been through this before
     if ($target instanceof User) {
         if (IP::isValid($target->getName())) {
             return array($target, self::TYPE_IP);
         } else {
             return array($target, self::TYPE_USER);
         }
     } elseif ($target === null) {
         return array(null, null);
     }
     $target = trim($target);
     if (IP::isValid($target)) {
         # We can still create a User if it's an IP address, but we need to turn
         # off validation checking (which would exclude IP addresses)
         return array(User::newFromName(IP::sanitizeIP($target), false), Block::TYPE_IP);
     } elseif (IP::isValidBlock($target)) {
         # Can't create a User from an IP range
         return array(IP::sanitizeRange($target), Block::TYPE_RANGE);
     }
     # Consider the possibility that this is not a username at all
     # but actually an old subpage (bug #29797)
     if (strpos($target, '/') !== false) {
         # An old subpage, drill down to the user behind it
         $parts = explode('/', $target);
         $target = $parts[0];
     }
     $userObj = User::newFromName($target);
     if ($userObj instanceof User) {
         # Note that since numbers are valid usernames, a $target of "12345" will be
         # considered a User.  If you want to pass a block ID, prepend a hash "#12345",
         # since hash characters are not valid in usernames or titles generally.
         return array($userObj, Block::TYPE_USER);
     } elseif (preg_match('/^#\\d+$/', $target)) {
         # Autoblock reference in the form "#12345"
         return array(substr($target, 1), Block::TYPE_AUTO);
     } else {
         # WTF?
         return array(null, null);
     }
 }
Пример #5
0
 /**
  * Roughly increments the cache misses in the last hour by unique visitors
  * @param WebRequest $request
  * @return void
  */
 public function incrMissesRecent(WebRequest $request)
 {
     if (mt_rand(0, self::MISS_FACTOR - 1) == 0) {
         $cache = ObjectCache::getLocalClusterInstance();
         # Get a large IP range that should include the user  even if that
         # person's IP address changes
         $ip = $request->getIP();
         if (!IP::isValid($ip)) {
             return;
         }
         $ip = IP::isIPv6($ip) ? IP::sanitizeRange("{$ip}/32") : IP::sanitizeRange("{$ip}/16");
         # Bail out if a request already came from this range...
         $key = wfMemcKey(get_class($this), 'attempt', $this->mType, $this->mKey, $ip);
         if ($cache->get($key)) {
             return;
             // possibly the same user
         }
         $cache->set($key, 1, self::MISS_TTL_SEC);
         # Increment the number of cache misses...
         $key = $this->cacheMissKey();
         if ($cache->get($key) === false) {
             $cache->set($key, 1, self::MISS_TTL_SEC);
         } else {
             $cache->incr($key);
         }
     }
 }
Пример #6
0
 public static function takeConsequenceAction($action, $parameters, $title, $vars, $rule_desc)
 {
     $display = '';
     switch ($action) {
         case 'disallow':
             if (strlen($parameters[0])) {
                 $display .= wfMsgExt($parameters[0], 'parseinline', array($rule_desc)) . "\n";
             } else {
                 // Generic message.
                 $display .= wfMsgExt('abusefilter-disallowed', 'parseinline', array($rule_desc)) . "<br />\n";
             }
             break;
         case 'block':
             global $wgUser, $wgAbuseFilterBlockDuration;
             $filterUser = AbuseFilter::getFilterUser();
             // Create a block.
             $block = new Block();
             $block->setTarget($wgUser->getName());
             $block->setBlocker($filterUser);
             $block->mReason = wfMsgForContent('abusefilter-blockreason', $rule_desc);
             $block->isHardblock(false);
             $block->prevents('createaccount', true);
             $block->mExpiry = SpecialBlock::parseExpiryInput($wgAbuseFilterBlockDuration);
             $block->insert();
             // Log it
             # Prepare log parameters
             $logParams = array();
             if ($block->mExpiry == 'infinity') {
                 $logParams[] = 'indefinite';
             } else {
                 $logParams[] = $wgAbuseFilterBlockDuration;
             }
             $logParams[] = 'nocreate, angry-autoblock';
             $log = new LogPage('block');
             $log->addEntry('block', Title::makeTitle(NS_USER, $wgUser->getName()), wfMsgForContent('abusefilter-blockreason', $rule_desc), $logParams, self::getFilterUser());
             $display .= wfMsgExt('abusefilter-blocked-display', 'parseinline', array($rule_desc)) . "<br />\n";
             break;
         case 'rangeblock':
             $filterUser = AbuseFilter::getFilterUser();
             $range = IP::sanitizeRange(wfGetIP() . '/16');
             // Create a block.
             $block = new Block();
             $block->setTarget($range);
             $block->setBlocker($filterUser);
             $block->mReason = wfMsgForContent('abusefilter-blockreason', $rule_desc);
             $block->isHardblock(false);
             $block->prevents('createaccount', true);
             $block->mExpiry = SpecialBlock::parseExpiryInput('1 week');
             $block->insert();
             // Log it
             # Prepare log parameters
             $logParams = array();
             $logParams[] = 'indefinite';
             $logParams[] = 'nocreate, angry-autoblock';
             $log = new LogPage('block');
             $log->addEntry('block', Title::makeTitle(NS_USER, $range), wfMsgForContent('abusefilter-blockreason', $rule_desc), $logParams, self::getFilterUser());
             $display .= wfMsgExt('abusefilter-blocked-display', 'parseinline', $rule_desc) . "<br />\n";
             break;
         case 'degroup':
             global $wgUser;
             if (!$wgUser->isAnon()) {
                 // Remove all groups from the user. Ouch.
                 $groups = $wgUser->getGroups();
                 foreach ($groups as $group) {
                     $wgUser->removeGroup($group);
                 }
                 $display .= wfMsgExt('abusefilter-degrouped', 'parseinline', array($rule_desc)) . "<br />\n";
                 // Don't log it if there aren't any groups being removed!
                 if (!count($groups)) {
                     break;
                 }
                 // Log it.
                 $log = new LogPage('rights');
                 $log->addEntry('rights', $wgUser->getUserPage(), wfMsgForContent('abusefilter-degroupreason', $rule_desc), array(implode(', ', $groups), wfMsgForContent('rightsnone')), self::getFilterUser());
             }
             break;
         case 'blockautopromote':
             global $wgUser, $wgMemc;
             if (!$wgUser->isAnon()) {
                 $blockPeriod = (int) mt_rand(3 * 86400, 7 * 86400);
                 // Block for 3-7 days.
                 $wgMemc->set(self::autoPromoteBlockKey($wgUser), true, $blockPeriod);
                 $display .= wfMsgExt('abusefilter-autopromote-blocked', 'parseinline', array($rule_desc)) . "<br />\n";
             }
             break;
         case 'flag':
             // Do nothing. Here for completeness.
             break;
         case 'tag':
             // Mark with a tag on recentchanges.
             global $wgUser;
             $actionID = implode('-', array($title->getPrefixedText(), $wgUser->getName(), $vars->getVar('ACTION')->toString()));
             AbuseFilter::$tagsToSet[$actionID] = $parameters;
             break;
         default:
             wfDebugLog('AbuseFilter', "Unrecognised action {$action}");
     }
     return $display;
 }