diff --git a/src/abuse/SecureShieldsUpAction.php b/src/abuse/SecureShieldsUpAction.php index 63f2d00..0ab1e5f 100644 --- a/src/abuse/SecureShieldsUpAction.php +++ b/src/abuse/SecureShieldsUpAction.php @@ -1,188 +1,190 @@ establishConnection('r'), 'SELECT authorPHID FROM %T WHERE objectPHID = %s ORDER BY id DESC LIMIT 1', id(new ManiphestTransaction())->getTableName(), $object->getPHID()); if (!$last_actor_row) { return; } $actor = id(new PhabricatorPeopleQuery()) ->setViewer(PhabricatorUser::getOmnipotentUser()) ->withPHIDs(array($last_actor_row['authorPHID'])) ->executeOne(); if (!$actor) { return; } if ($this->isFriendlyUser($actor)) { return; } if (!$this->isHostileObject($object)) { return; } $this->quarantineUser($actor); $this->quarantineObject($object); $this->logEffect(self::DO_SHIELD); } public function getHeraldActionStandardType() { return self::STANDARD_NONE; } public function renderActionDescription($value) { return pht('Shields up.'); } protected function getActionEffectMap() { return array( self::DO_SHIELD => array( 'icon' => 'fa-umbrella', 'color' => 'indigo', 'name' => pht('Shields Up'), ), ); } protected function renderActionEffectDescription($type, $data) { switch ($type) { case self::DO_SHIELD: return pht('Shields up.'); } } private function isFriendlyUser(PhabricatorUser $user) { if ($user->getIsAdmin()) { return true; } return false; } private function isHostileObject($object) { $content = array(); if ($object instanceof ManiphestTask) { $content[] = $object->getTitle(); $content[] = $object->getDescription(); } $content = implode("\n\n", $content); $patterns = array(); // Phone numbers that we'll reject. $numbers = array( '8443133901', '8007909186', '800059007', '8008101018', '8002044122', '8007992667', '8557092847', '8007789936', + '8000903859', + '8000314244', ); if (self::matchPhoneNumbers($numbers, $content)) { return true; } return false; } public static function matchPhoneNumbers(array $numbers, $content) { $swap = array( 'o' => '0', 'O' => '0', '@' => '0', '()' => '0', 'i' => '1', 'I' => '1', '|' => '1', 'l' => '1', ); $content = str_replace( array_keys($swap), array_values($swap), $content); foreach ($numbers as $number) { $regex = array(); for ($ii = 0; $ii < strlen($number); $ii++) { $regex[] = $number[$ii]; } // Reject all variants of the number with other random punctuation or // spaces between the digits. $regex = implode('[^\\d]{0,6}', $regex); $patterns[] = '/'.$regex.'/'; } foreach ($patterns as $pattern) { if (preg_match($pattern, $content)) { return true; } } return false; } private function quarantineUser(PhabricatorUser $user) { // For now, just log the user out of all their sessions so it's not a big // deal if we hit a friendly user by accident. We could make this more // extreme in the future. $sessions = id(new PhabricatorAuthSessionQuery()) ->setViewer($user) ->withIdentityPHIDs(array($user->getPHID())) ->execute(); foreach ($sessions as $session) { $session->delete(); } } private function quarantineObject($object) { $title = $object->getTitle(); $new_title = ' '.$title; $object ->setTitle($new_title) ->setViewPolicy(PhabricatorPolicies::POLICY_ADMIN) ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN) ->save(); } }