*/ /** * @class spamfilterController * @author NAVER (developers@xpressengine.com) * @brief The controller class for the spamfilter module */ class SpamfilterController extends Spamfilter { /** * List of actions to use CAPTCHA. */ protected static $_captcha_actions = array( 'signup' => '/^(?:disp|proc)Member(?:SignUp|Insert$)/i', 'login' => '/^(?:disp|proc)MemberLogin(?:Form)?/i', 'recovery' => '/^(?:disp|proc)Member(?:FindAccount|ResendAuthMail)/i', 'document' => '/^(?:disp|proc)Board(Write|InsertDocument)/i', 'comment' => '/^(?:disp|proc)Board(Content|InsertComment|ModifyComment|ReplyComment)/i', ); /** * @brief Initialization */ function init() { } /** * @brief Call this function in case you need to stop the spam filter's usage during the batch work */ function setAvoidLog() { $_SESSION['avoid_log'] = true; } /** * @brief The routine process to check the time it takes to store a document, when writing it, and to ban IP/word */ function triggerInsertDocument(&$obj) { if (!empty($_SESSION['avoid_log'])) { return; } // Check the login status, login information, and permission $is_logged = Context::get('is_logged'); $logged_info = Context::get('logged_info'); $grant = Context::get('grant'); // In case logged in, check if it is an administrator if($is_logged) { if($logged_info->is_admin == 'Y') return; if($grant->manager) return; } // Check if the IP is prohibited $output = SpamfilterModel::isDeniedIP(); if(!$output->toBool()) { $config = SpamfilterModel::getConfig(); if (!isset($config->blocked_actions) || in_array('document', $config->blocked_actions)) { return $output; } } // Check if there is a ban on the word $filter_targets = [$obj->title, $obj->content, $obj->tags ?? '']; if(!$is_logged) { $filter_targets[] = $obj->nick_name; $filter_targets[] = $obj->homepage; } foreach ($obj as $key => $val) { if (preg_match('/^extra_vars\d+$/', $key) && !empty($val)) { foreach (is_array($val) ? $val : explode('|@|', $val) as $fragment) { $filter_targets[] = $fragment; } } } $output = SpamfilterModel::isDeniedWord(implode("\n", $filter_targets)); if(!$output->toBool()) { return $output; } // Check the specified time beside the modificaiton time if($obj->document_srl == 0) { $output = SpamfilterModel::checkLimited(); if(!$output->toBool()) return $output; } // Save a log $this->insertLog(); } /** * @brief The routine process to check the time it takes to store a comment, and to ban IP/word */ function triggerInsertComment(&$obj) { if (!empty($_SESSION['avoid_log'])) { return; } // Check the login status, login information, and permission $is_logged = Context::get('is_logged'); $logged_info = Context::get('logged_info'); $grant = Context::get('grant'); // In case logged in, check if it is an administrator if($is_logged) { if($logged_info->is_admin == 'Y') return; if($grant->manager) return; } // Check if the IP is prohibited $output = SpamfilterModel::isDeniedIP(); if(!$output->toBool()) { $config = SpamfilterModel::getConfig(); if (!isset($config->blocked_actions) || in_array('comment', $config->blocked_actions)) { return $output; } } // Check if there is a ban on the word if($is_logged) { $text = $obj->content; } else { $text = $obj->content . ' ' . $obj->nick_name . ' ' . $obj->homepage; } $output = SpamfilterModel::isDeniedWord($text); if(!$output->toBool()) return $output; // If the specified time check is not modified if(!$obj->__isupdate) { $output = SpamfilterModel::checkLimited(); if(!$output->toBool()) return $output; } unset($obj->__isupdate); // Save a log $this->insertLog(); } /** * @brief IP registration * The registered IP address is considered as a spammer */ function insertIP($ipaddress_list, $description = null) { if (!is_array($ipaddress_list)) { $ipaddress_list = array_map('trim', explode("\n", $ipaddress_list)); } $fail_list = ''; $output = null; foreach ($ipaddress_list as $ipaddress) { if ($ipaddress === '') { continue; } $args = new stdClass; if (preg_match('@^(.+?)(?://|#)(.*)$@', $ipaddress, $matches)) { $args->ipaddress = trim($matches[1]); $args->description = trim($matches[2]); } else { $args->ipaddress = $ipaddress; $args->description = $description; } if (!Rhymix\Framework\Filters\IpFilter::validateRange($args->ipaddress)) { return new BaseObject(-1, 'msg_invalid_ip'); } $output = executeQuery('spamfilter.insertDeniedIP', $args); if (!$output->toBool()) { $fail_list .= $args->ipaddress . '
'; } } if ($output) { $output->add('fail_list', $fail_list); } Rhymix\Framework\Cache::delete('spamfilter:denied_ip_list'); return $output; } /** * Block voting from a spam IP. */ function triggerVote(&$obj) { if (!empty($_SESSION['avoid_log'])) { return; } if ($this->user->isAdmin() || (Context::get('grant')->manager ?? false)) { return; } $config = SpamfilterModel::getConfig(); if ($obj->point > 0 && isset($config->blocked_actions) && !in_array('vote_up', $config->blocked_actions)) { return; } if ($obj->point < 0 && isset($config->blocked_actions) && !in_array('vote_down', $config->blocked_actions)) { return; } $output = SpamfilterModel::isDeniedIP(); if (!$output->toBool()) { return $output; } } /** * Block reporting from a spam IP. */ function triggerDeclare(&$obj) { if (!empty($_SESSION['avoid_log'])) { return; } if ($this->user->isAdmin() || (Context::get('grant')->manager ?? false)) { return; } $config = SpamfilterModel::getConfig(); if (isset($config->blocked_actions) && !in_array('declare', $config->blocked_actions)) { return; } $output = SpamfilterModel::isDeniedIP(); if (!$output->toBool()) { return $output; } } /** * @brief The routine process to check the time it takes to store a message, when writing it, and to ban IP/word */ function triggerSendMessage(&$obj) { if($this->user->isAdmin() || !empty($_SESSION['avoid_log'])) { return; } if(isset($obj->use_spamfilter) && $obj->use_spamfilter === false) { return; } // Check if the IP is prohibited $output = SpamfilterModel::isDeniedIP(); if(!$output->toBool()) { $config = SpamfilterModel::getConfig(); if (!isset($config->blocked_actions) || in_array('message', $config->blocked_actions)) { return $output; } } // Check if there is a ban on the word $text = $obj->title . ' ' . $obj->content; $output = SpamfilterModel::isDeniedWord($text); if(!$output->toBool()) return $output; // Check the specified time $output = SpamfilterModel::checkLimited(TRUE); if(!$output->toBool()) return $output; // Save a log $this->insertLog(); } /** * @brief while document manager is running, stop filter */ function triggerManageDocument(&$obj) { $this->setAvoidLog(); } /** * Trigger to check CAPTCHA. */ function triggerCheckCaptcha(&$obj) { $config = ModuleModel::getModuleConfig('spamfilter'); if (!SpamfilterModel::isCaptchaEnabled()) { return; } $target_actions = []; foreach (['signup', 'login', 'recovery', 'document', 'comment'] as $action) { if ($config->captcha->target_actions[$action]) { if (preg_match(self::$_captcha_actions[$action], $obj->act) || ($action === 'comment' && (!$obj->act || $obj->act === 'dispBoardContent') && Context::get('document_srl'))) { $target_actions[$action] = true; } } } if (count($target_actions)) { $captcha_class = 'Rhymix\\Modules\\Spamfilter\\Captcha\\' . $config->captcha->type; $captcha_class::init($config->captcha); if (strncasecmp('proc', $obj->act, 4) === 0) { $captcha_class::check(); } else { $captcha = new $captcha_class(); $captcha->setTargetActions($target_actions); $captcha->addScripts(); Context::set('captcha', $captcha); } } } /** * @brief Log registration * Register the newly accessed IP address in the log. In case the log interval is withing a certain time, * register it as a spammer */ function insertLog() { $output = executeQuery('spamfilter.insertLog'); return $output; } } /* End of file spamfilter.controller.php */ /* Location: ./modules/spamfilter/spamfilter.controller.php */