From 3d571142a46a5b90f8999893adea1d29a1ff0fd5 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 17:14:08 +0900 Subject: [PATCH 01/12] Prevent utf8mb4 overflow in spamfilter tables --- modules/spamfilter/schemas/spamfilter_denied_ip.xml | 4 ++-- modules/spamfilter/schemas/spamfilter_denied_word.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/spamfilter/schemas/spamfilter_denied_ip.xml b/modules/spamfilter/schemas/spamfilter_denied_ip.xml index eba59c51d..4911300fb 100644 --- a/modules/spamfilter/schemas/spamfilter_denied_ip.xml +++ b/modules/spamfilter/schemas/spamfilter_denied_ip.xml @@ -1,5 +1,5 @@ - - + +
diff --git a/modules/spamfilter/schemas/spamfilter_denied_word.xml b/modules/spamfilter/schemas/spamfilter_denied_word.xml index 7ecb6a5be..ee6dab2d7 100644 --- a/modules/spamfilter/schemas/spamfilter_denied_word.xml +++ b/modules/spamfilter/schemas/spamfilter_denied_word.xml @@ -1,5 +1,5 @@ - + From e2df99d44034476ede1e5b32c5b12816fc561335 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 17:14:42 +0900 Subject: [PATCH 02/12] Update spamfilter to use Rhymix IP filter --- modules/spamfilter/spamfilter.controller.php | 45 ++++++++++++++------ modules/spamfilter/spamfilter.model.php | 21 ++++----- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/modules/spamfilter/spamfilter.controller.php b/modules/spamfilter/spamfilter.controller.php index 45ff85fa9..e5a88ad1e 100644 --- a/modules/spamfilter/spamfilter.controller.php +++ b/modules/spamfilter/spamfilter.controller.php @@ -164,25 +164,44 @@ class spamfilterController extends spamfilter */ function insertIP($ipaddress_list, $description = null) { - $regExr = "/^((\d{1,3}(?:.(\d{1,3}|\*)){3})\s*(\/\/(.*)\s*)?)*\s*$/"; - if(!preg_match($regExr,$ipaddress_list)) return new Object(-1, 'msg_invalid'); - $ipaddress_list = str_replace("\r","",$ipaddress_list); - $ipaddress_list = explode("\n",$ipaddress_list); - foreach($ipaddress_list as $ipaddressValue) + if (!is_array($ipaddress_list)) { - $args = new stdClass(); - preg_match("/(\d{1,3}(?:.(\d{1,3}|\*)){3})\s*(\/\/(.*)\s*)?/",$ipaddressValue,$matches); - if($ipaddress=trim($matches[1])) + $ipaddress_list = array_map('trim', explode("\n", $ipaddress_list)); + } + $fail_list = ''; + $output = null; + + foreach ($ipaddress_list as $ipaddress) + { + $args = new stdClass; + if (preg_match('@^(.+?)(?://|#)(.*)$@', $ipaddress, $matches)) + { + $args->ipaddress = trim($matches[1]); + $args->description = trim($matches[2]); + } + else { $args->ipaddress = $ipaddress; - if(!$description && $matches[4]) $args->description = $matches[4]; - else $args->description = $description; + $args->description = $description; } + + if (!Rhymix\Framework\Filters\IpFilter::validateRange($args->ipaddress)) + { + return new Object(-1, 'msg_invalid'); + } + $output = executeQuery('spamfilter.insertDeniedIP', $args); - if(!$output->toBool()) $fail_list .= $ipaddress.'
'; + if (!$output->toBool()) + { + $fail_list .= $args->ipaddress . '
'; + } } - - $output->add('fail_list',$fail_list); + + if ($output) + { + $output->add('fail_list', $fail_list); + } + return $output; } diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index e39651597..452cc5a4c 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -32,9 +32,8 @@ class spamfilterModel extends spamfilter $args = new stdClass(); $args->sort_index = "regdate"; $args->page = Context::get('page')?Context::get('page'):1; - $output = executeQuery('spamfilter.getDeniedIPList', $args); + $output = executeQueryArray('spamfilter.getDeniedIPList', $args); if(!$output->data) return; - if(!is_array($output->data)) return array($output->data); return $output->data; } @@ -43,18 +42,20 @@ class spamfilterModel extends spamfilter */ function isDeniedIP() { - $ipaddress = $_SERVER['REMOTE_ADDR']; - $ip_list = $this->getDeniedIPList(); if(!count($ip_list)) return new Object(); - - $count = count($ip_list); - for($i=0;$i<$count;$i++) + + $ip_ranges = array(); + foreach ($ip_list as $ip_range) { - $ip = str_replace('.', '\.', str_replace('*','(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)',$ip_list[$i]->ipaddress)); - if(preg_match('/^'.$ip.'$/', $ipaddress, $matches)) return new Object(-1,'msg_alert_registered_denied_ip'); + $ip_ranges[] = $ip_range->ipaddress; } - + + if (Rhymix\Framework\Filters\IpFilter::inRanges(\RX_CLIENT_IP, $ip_ranges)) + { + return new Object(-1, 'msg_alert_registered_denied_ip'); + } + return new Object(); } From 2b798bffb7dd2a77813b8d7fdb26e5dc27cf0430 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 19:52:33 +0900 Subject: [PATCH 03/12] Remove unnecessary regexp in isDeniedWord() --- modules/spamfilter/spamfilter.model.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index 452cc5a4c..6518e8089 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -80,11 +80,10 @@ class spamfilterModel extends spamfilter $word_list = $this->getDeniedWordList(); if(!count($word_list)) return new Object(); - $count = count($word_list); - for($i=0;$i<$count;$i++) + foreach ($word_list as $word_item) { - $word = $word_list[$i]->word; - if(preg_match('/'.preg_quote($word,'/').'/is', $text)) + $word = $word_item->word; + if (strpos($text, $word) !== false) { $args = new stdClass(); $args->word = $word; From 6ecdd499e4239d4405f4ccb29cd028f4dffa4ad6 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 20:04:38 +0900 Subject: [PATCH 04/12] Use RX_CLIENT_IP to determine IP in spamfilter module --- modules/spamfilter/spamfilter.model.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index 6518e8089..a0de997c4 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -108,12 +108,11 @@ class spamfilterModel extends spamfilter $count = $this->getLogCount($interval); - $ipaddress = $_SERVER['REMOTE_ADDR']; // Ban the IP address if the interval is exceeded if($count>=$limit_count) { $oSpamFilterController = getController('spamfilter'); - $oSpamFilterController->insertIP($ipaddress, 'AUTO-DENIED : Over limit'); + $oSpamFilterController->insertIP(\RX_CLIENT_IP, 'AUTO-DENIED : Over limit'); return new Object(-1, 'msg_alert_registered_denied_ip'); } // If the number of limited posts is not reached, keep creating. @@ -142,7 +141,7 @@ class spamfilterModel extends spamfilter function isInsertedTrackback($document_srl) { $oTrackbackModel = getModel('trackback'); - $count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, $_SERVER['REMOTE_ADDR']); + $count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, \RX_CLIENT_IP); if($count>0) return new Object(-1, 'msg_alert_trackback_denied'); return new Object(); @@ -153,11 +152,11 @@ class spamfilterModel extends spamfilter */ function getLogCount($time = 60, $ipaddress='') { - if(!$ipaddress) $ipaddress = $_SERVER['REMOTE_ADDR']; + if(!$ipaddress) $ipaddress = \RX_CLIENT_IP; $args = new stdClass(); $args->ipaddress = $ipaddress; - $args->regdate = date("YmdHis", $_SERVER['REQUEST_TIME']-$time); + $args->regdate = date("YmdHis", time() - $time); $output = executeQuery('spamfilter.getLogCount', $args); $count = $output->data->count; return $count; From 0af94a227575f2139fa360f3a06f14b3bc6c5542 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 20:05:01 +0900 Subject: [PATCH 05/12] Clean up insertWord() --- .../spamfilter.admin.controller.php | 39 ++++++++++++------- modules/spamfilter/spamfilter.controller.php | 5 +++ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/modules/spamfilter/spamfilter.admin.controller.php b/modules/spamfilter/spamfilter.admin.controller.php index d2e78244c..9f8eadd25 100644 --- a/modules/spamfilter/spamfilter.admin.controller.php +++ b/modules/spamfilter/spamfilter.admin.controller.php @@ -114,27 +114,38 @@ class spamfilterAdminController extends spamfilter */ function insertWord($word_list) { - - $word_list = str_replace("\r","",$word_list); - $word_list = explode("\n",$word_list); - - foreach($word_list as $word) + if (!is_array($word_list)) { - if(!preg_match("/^(.{2,40}[\r\n]+)*.{2,40}$/", $word)) + $word_list = array_map('trim', explode("\n", $word_list)); + } + $fail_list = ''; + $output = null; + + foreach ($word_list as $word) + { + if ($word === '') + { + continue; + } + + if (mb_strlen($word, 'UTF-8') < 2 || mb_strlen($word, 'UTF-8') > 40) { return new Object(-1, 'msg_invalid'); } - } - - $fail_word = ''; - foreach($word_list as $word) - { + $args = new stdClass; - if(trim($word)) $args->word = $word; + $args->word = $word; $output = executeQuery('spamfilter.insertDeniedWord', $args); - if(!$output->toBool()) $fail_word .= $word.'
'; + if (!$output->toBool()) + { + $fail_list .= $args->word . '
'; + } + } + + if ($output) + { + $output->add('fail_list', $fail_list); } - $output->add('fail_list',$fail_word); return $output; } diff --git a/modules/spamfilter/spamfilter.controller.php b/modules/spamfilter/spamfilter.controller.php index e5a88ad1e..21ce45f7f 100644 --- a/modules/spamfilter/spamfilter.controller.php +++ b/modules/spamfilter/spamfilter.controller.php @@ -173,6 +173,11 @@ class spamfilterController extends spamfilter foreach ($ipaddress_list as $ipaddress) { + if ($ipaddress === '') + { + continue; + } + $args = new stdClass; if (preg_match('@^(.+?)(?://|#)(.*)$@', $ipaddress, $matches)) { From 278801ca0134c2a067fbc63efb144e3d38ee6486 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 20:08:54 +0900 Subject: [PATCH 06/12] Don't throw fatal error if trackback module is not installed --- modules/spamfilter/spamfilter.controller.php | 28 +++++++------------- modules/spamfilter/spamfilter.model.php | 11 +++++--- 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/modules/spamfilter/spamfilter.controller.php b/modules/spamfilter/spamfilter.controller.php index 21ce45f7f..149cd829c 100644 --- a/modules/spamfilter/spamfilter.controller.php +++ b/modules/spamfilter/spamfilter.controller.php @@ -128,32 +128,24 @@ class spamfilterController extends spamfilter // Check if the IP is prohibited $output = $oFilterModel->isDeniedIP(); if(!$output->toBool()) return $output; + // Check if there is a ban on the word $text = $obj->blog_name . ' ' . $obj->title . ' ' . $obj->excerpt . ' ' . $obj->url; $output = $oFilterModel->isDeniedWord($text); if(!$output->toBool()) return $output; + // Start Filtering - $oTrackbackModel = getModel('trackback'); $oTrackbackController = getController('trackback'); - - list($ipA,$ipB,$ipC,$ipD) = explode('.',$_SERVER['REMOTE_ADDR']); - $ipaddress = $ipA.'.'.$ipB.'.'.$ipC; - // In case the title and the blog name are indentical, investigate the IP address of the last 6 hours, delete and ban it. - if($obj->title == $obj->excerpt) + if (is_object($oTrackbackController) && method_exists($oTrackbackController, 'deleteTrackbackSender')) { - $oTrackbackController->deleteTrackbackSender(60*60*6, $ipaddress, $obj->url, $obj->blog_name, $obj->title, $obj->excerpt); - $this->insertIP($ipaddress.'.*', 'AUTO-DENIED : trackback.insertTrackback'); - return new Object(-1,'msg_alert_trackback_denied'); + // In case the title and the blog name are indentical, investigate the IP address of the last 6 hours, delete and ban it. + if($obj->title == $obj->excerpt) + { + $oTrackbackController->deleteTrackbackSender(60*60*6, \RX_CLIENT_IP, $obj->url, $obj->blog_name, $obj->title, $obj->excerpt); + $this->insertIP(\RX_CLIENT_IP, 'AUTO-DENIED : trackback.insertTrackback'); + return new Object(-1, 'msg_alert_trackback_denied'); + } } - // If trackbacks have been registered by one C-class IP address more than once for the last 30 minutes, ban the IP address and delete all the posts - /* 호스팅 환경을 감안하여 일단 이 부분은 동작하지 않도록 주석 처리 - $count = $oTrackbackModel->getRegistedTrackback(30*60, $ipaddress, $obj->url, $obj->blog_name, $obj->title, $obj->excerpt); - if($count > 1) { - $oTrackbackController->deleteTrackbackSender(3*60, $ipaddress, $obj->url, $obj->blog_name, $obj->title, $obj->excerpt); - $this->insertIP($ipaddress.'.*'); - return new Object(-1,'msg_alert_trackback_denied'); - } - */ return new Object(); } diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index a0de997c4..43b1ca9d9 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -141,9 +141,14 @@ class spamfilterModel extends spamfilter function isInsertedTrackback($document_srl) { $oTrackbackModel = getModel('trackback'); - $count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, \RX_CLIENT_IP); - if($count>0) return new Object(-1, 'msg_alert_trackback_denied'); - + if (is_object($oTrackbackModel) && method_exists($oTrackbackModel, 'getTrackbackCountByIPAddress')) + { + $count = $oTrackbackModel->getTrackbackCountByIPAddress($document_srl, \RX_CLIENT_IP); + if ($count > 0) + { + return new Object(-1, 'msg_alert_trackback_denied'); + } + } return new Object(); } From 81a242fa88bd5455ab72a84970fb5dcc10b41a45 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 20:14:50 +0900 Subject: [PATCH 07/12] Separate IP error message from keyword error message --- modules/spamfilter/lang/en.php | 5 +++-- modules/spamfilter/lang/ja.php | 3 ++- modules/spamfilter/lang/ko.php | 5 +++-- modules/spamfilter/spamfilter.admin.controller.php | 2 +- modules/spamfilter/spamfilter.controller.php | 2 +- 5 files changed, 10 insertions(+), 7 deletions(-) diff --git a/modules/spamfilter/lang/en.php b/modules/spamfilter/lang/en.php index 42f5186c5..798b9bb3a 100644 --- a/modules/spamfilter/lang/en.php +++ b/modules/spamfilter/lang/en.php @@ -26,5 +26,6 @@ $lang->cmd_check_trackback = 'Do you want to blacklist the users who attempt to $lang->add = 'Add'; $lang->yes = 'Yes'; $lang->no = 'No'; -$lang->msg_duplicate = 'The value is invalid.'; -$lang->msg_invalid = 'The value is invalid.'; +$lang->msg_duplicate = 'Duplicate'; +$lang->msg_invalid_ip = 'Invalid IP address format.'; +$lang->msg_invalid_word = 'Spam keywords must be between 2 and 40 characters.'; diff --git a/modules/spamfilter/lang/ja.php b/modules/spamfilter/lang/ja.php index 4950f1169..19a8cbe5f 100644 --- a/modules/spamfilter/lang/ja.php +++ b/modules/spamfilter/lang/ja.php @@ -28,5 +28,6 @@ $lang->add = '追加'; $lang->yes = 'はい'; $lang->no = 'いいえ'; $lang->msg_duplicate = '既に存在します。'; -$lang->msg_invalid = '形式が有効しません。'; +$lang->msg_invalid_ip = 'IPアドレスの形式が正しくありません。'; +$lang->msg_invalid_word = 'スパムキーワードは2〜40文字の範囲で指定します。'; $lang->msg_faillist = '
失敗(既に存在します。)
%s '; diff --git a/modules/spamfilter/lang/ko.php b/modules/spamfilter/lang/ko.php index 614c1bbe9..26f96ada3 100644 --- a/modules/spamfilter/lang/ko.php +++ b/modules/spamfilter/lang/ko.php @@ -15,7 +15,7 @@ $lang->latest_hit = '최근 히트'; $lang->about_interval = '지정된 시간 내에 글을 등록하지 못하게 합니다.'; $lang->about_limit_count = '지정된 시간 내에 제한수를 넘겨서 글 작성을 시도하면 스팸으로 인식, 해당 IP의 글 작성, 댓글 작성, 트랙백 발송, 쪽지 발송 등을 금지합니다.'; $lang->about_denied_ip = '\'스팸 IP // 메모\' 형식으로 입력하세요. 여러개의 항목은 줄을 바꾸어 입력하세요.'; -$lang->about_denied_word = '여러개의 항목은 줄을 바꾸어 입력하세요. (글자 제한 2~40 byte)'; +$lang->about_denied_word = '여러개의 항목은 줄을 바꾸어 입력하세요. (2~40자)'; $lang->about_check_trackback = '한 글에 한 IP에만 트랙백을 허용할 수 있습니다.'; $lang->msg_alert_limited_by_config = '%s 초 이내에 글 작성은 금지 됩니다. 계속 시도하면 금지 IP에 등록될 수 있습니다.'; $lang->msg_alert_limited_message_by_config = '%s 초 이내에 쪽지 발송은 금지 됩니다. 계속 시도하면 금지 IP에 등록될 수 있습니다.'; @@ -28,5 +28,6 @@ $lang->add = '추가'; $lang->yes = '예'; $lang->no = '아니오'; $lang->msg_duplicate = '이미 존재합니다.'; -$lang->msg_invalid = '형식이 유효하지 않습니다.'; +$lang->msg_invalid_ip = 'IP 주소 형식이 올바르지 않습니다.'; +$lang->msg_invalid_word = '스팸 키워드는 2~40자 사이여야 합니다.'; $lang->msg_faillist = '
실패(이미 존재합니다.)
%s '; diff --git a/modules/spamfilter/spamfilter.admin.controller.php b/modules/spamfilter/spamfilter.admin.controller.php index 9f8eadd25..485a51a88 100644 --- a/modules/spamfilter/spamfilter.admin.controller.php +++ b/modules/spamfilter/spamfilter.admin.controller.php @@ -130,7 +130,7 @@ class spamfilterAdminController extends spamfilter if (mb_strlen($word, 'UTF-8') < 2 || mb_strlen($word, 'UTF-8') > 40) { - return new Object(-1, 'msg_invalid'); + return new Object(-1, 'msg_invalid_word'); } $args = new stdClass; diff --git a/modules/spamfilter/spamfilter.controller.php b/modules/spamfilter/spamfilter.controller.php index 149cd829c..47200e00c 100644 --- a/modules/spamfilter/spamfilter.controller.php +++ b/modules/spamfilter/spamfilter.controller.php @@ -184,7 +184,7 @@ class spamfilterController extends spamfilter if (!Rhymix\Framework\Filters\IpFilter::validateRange($args->ipaddress)) { - return new Object(-1, 'msg_invalid'); + return new Object(-1, 'msg_invalid_ip'); } $output = executeQuery('spamfilter.insertDeniedIP', $args); From 5cab16418ed5722fe31e199172e2e0acc1d39e32 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 22:04:14 +0900 Subject: [PATCH 08/12] Add more unit tests for IpFilter --- tests/unit/framework/filters/IpFilterTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/unit/framework/filters/IpFilterTest.php b/tests/unit/framework/filters/IpFilterTest.php index 5da4b2f97..19342929d 100644 --- a/tests/unit/framework/filters/IpFilterTest.php +++ b/tests/unit/framework/filters/IpFilterTest.php @@ -10,6 +10,9 @@ class IpFilterTest extends \Codeception\TestCase\Test $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('172.34.0.0', '172.16.0.0/12')); $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.16.0/22')); $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.16.0/23')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.19.7/23')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.16.211/22')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.18.214', '192.168.17.255/23')); } public function testIPv6CIDR() @@ -18,14 +21,18 @@ class IpFilterTest extends \Codeception\TestCase\Test $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('::1', '::2')); $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('2400:cb00::1234', '2400:cb00::/32')); $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('2405:8100::1234', '2400:cb00::/32')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('2400:cb00::1234', '2400:cb00::ffff:1234/96')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('2405:8100::1234', '2400:cb00::ffff:1234/96')); } public function testIPv4Wildcard() { $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.134.*')); $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.*.*')); + $this->assertTrue(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.*')); $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.168.136.*')); $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.172.*.*')); + $this->assertFalse(Rhymix\Framework\Filters\IpFilter::inRange('192.168.134.241', '192.172.*')); } public function testIPv4Hyphen() From aef7f01ed97deac3091d796d595c777eb68d9063 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 22:32:38 +0900 Subject: [PATCH 09/12] Allow automatically blocking a range of IPs when spam is detected --- modules/spamfilter/lang/ko.php | 13 ++-- .../spamfilter.admin.controller.php | 28 ++++++-- modules/spamfilter/spamfilter.model.php | 12 +++- modules/spamfilter/tpl/config_block.html | 70 ++++++++++++++----- 4 files changed, 93 insertions(+), 30 deletions(-) diff --git a/modules/spamfilter/lang/ko.php b/modules/spamfilter/lang/ko.php index 26f96ada3..442f5f1aa 100644 --- a/modules/spamfilter/lang/ko.php +++ b/modules/spamfilter/lang/ko.php @@ -22,11 +22,16 @@ $lang->msg_alert_limited_message_by_config = '%s 초 이내에 쪽지 발송은 $lang->msg_alert_denied_word = '"%s"는 사용 금지된 단어입니다.'; $lang->msg_alert_registered_denied_ip = '금지 IP에 등록되어 정상적인 활동에 제한을 받게 됐습니다. 사이트 관리자에게 문의 바랍니다.'; $lang->msg_alert_trackback_denied = '한 글에는 하나의 트랙백만 허용됩니다.'; -$lang->cmd_interval = '10초 동안 3회 이상 글을 작성하면 스패머로 간주하시겠습니까? 글, 댓글 작성과 엮인글 발송, 쪽지 발송을 차단합니다.'; -$lang->cmd_check_trackback = '하나의 글에 2회 이상 엮인글을 등록하면 스패머로 간주하시겠습니까? 엮인글을 차단합니다.'; +$lang->cmd_interval = '글, 댓글 스팸 차단'; +$lang->cmd_interval_help = '10초 동안 3회 이상 글이나 댓글을 작성하면 스패머로 간주하고 글, 댓글 작성과 엮인글 발송, 쪽지 발송을 차단합니다.'; +$lang->cmd_check_trackback = '트랙백 스팸 차단'; +$lang->cmd_check_trackback_help = '하나의 글에 2회 이상 엮인글을 등록하면 스패머로 간주하고 엮인글을 차단합니다.
트랙백 모듈이 설치되어 있는 경우에만 적용됩니다.'; +$lang->cmd_ipv4_block_range = 'IPv4 차단 범위'; +$lang->cmd_ipv6_block_range = 'IPv6 차단 범위'; +$lang->cmd_block_range_self = '해당 IP만 차단'; +$lang->cmd_block_range_help = '스패머 발견시 비슷한 대역의 IP를 한꺼번에 차단할 수 있습니다.
지나치게 광범위하게 차단하면 정상적인 사용자에게 피해가 발생할 수 있으니 주의하시기 바랍니다.'; +$lang->cmd_block_range = '마지막 %s자리가 같은 IP를 모두 차단'; $lang->add = '추가'; -$lang->yes = '예'; -$lang->no = '아니오'; $lang->msg_duplicate = '이미 존재합니다.'; $lang->msg_invalid_ip = 'IP 주소 형식이 올바르지 않습니다.'; $lang->msg_invalid_word = '스팸 키워드는 2~40자 사이여야 합니다.'; diff --git a/modules/spamfilter/spamfilter.admin.controller.php b/modules/spamfilter/spamfilter.admin.controller.php index 485a51a88..29cdc3fe7 100644 --- a/modules/spamfilter/spamfilter.admin.controller.php +++ b/modules/spamfilter/spamfilter.admin.controller.php @@ -17,16 +17,32 @@ class spamfilterAdminController extends spamfilter function procSpamfilterAdminInsertConfig() { // Get the default information - $argsConfig = Context::gets('limits','check_trackback'); - $flag = Context::get('flag'); - //interval, limit_count - if($argsConfig->check_trackback!='Y') $argsConfig->check_trackback = 'N'; - if($argsConfig->limits!='Y') $argsConfig->limits = 'N'; + $args = Context::gets('limits', 'check_trackback', 'ipv4_block_range', 'ipv6_block_range'); + + // Set default values + if ($args->limits != 'Y') + { + $args->limits = 'N'; + } + if ($args->check_trackback != 'Y') + { + $args->check_trackback = 'N'; + } + if (!preg_match('#^/(\d+)$#', $args->ipv4_block_range, $matches) || $matches[1] > 32 || $matches[1] < 16) + { + $args->ipv4_block_range = ''; + } + if (!preg_match('#^/(\d+)$#', $args->ipv6_block_range, $matches) || $matches[1] > 128 || $matches[1] < 64) + { + $args->ipv6_block_range = ''; + } + // Create and insert the module Controller object $oModuleController = getController('module'); - $moduleConfigOutput = $oModuleController->insertModuleConfig('spamfilter',$argsConfig); + $moduleConfigOutput = $oModuleController->insertModuleConfig('spamfilter', $args); if(!$moduleConfigOutput->toBool()) return $moduleConfigOutput; + $this->setMessage('success_updated'); $returnUrl = Context::get('success_return_url') ? Context::get('success_return_url') : getNotEncodedUrl('', 'module', 'admin', 'act', 'dispSpamfilterAdminConfigBlock'); $this->setRedirectUrl($returnUrl); } diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index 43b1ca9d9..623b8714c 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -111,10 +111,20 @@ class spamfilterModel extends spamfilter // Ban the IP address if the interval is exceeded if($count>=$limit_count) { + if (\RX_CLIENT_IP_VERSION == 4) + { + $suffix = $config->ipv4_block_range ?: ''; + } + else + { + $suffix = $config->ipv6_block_range ?: ''; + } + $oSpamFilterController = getController('spamfilter'); - $oSpamFilterController->insertIP(\RX_CLIENT_IP, 'AUTO-DENIED : Over limit'); + $oSpamFilterController->insertIP(\RX_CLIENT_IP . $suffix, 'AUTO-DENIED : Over limit'); return new Object(-1, 'msg_alert_registered_denied_ip'); } + // If the number of limited posts is not reached, keep creating. if($count) { diff --git a/modules/spamfilter/tpl/config_block.html b/modules/spamfilter/tpl/config_block.html index 3403bf55a..f1965cd17 100644 --- a/modules/spamfilter/tpl/config_block.html +++ b/modules/spamfilter/tpl/config_block.html @@ -5,32 +5,64 @@
  • {$lang->cmd_denied_word}
  • {$lang->cmd_config_block}
  • -
    +
    -

    {$lang->cmd_interval}

    - - + +
    + + +

    {$lang->cmd_interval_help}

    +
    -

    {$lang->cmd_check_trackback}

    - - + +
    + + +

    {$lang->cmd_check_trackback_help}

    +
    +
    +
    + +
    + +

    {$lang->cmd_block_range_help}

    +
    +
    +
    + +
    + +

    {$lang->cmd_block_range_help}

    +
    From 68c0ce3ae699f7929f5b75309aec0a10864400e4 Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 22:59:02 +0900 Subject: [PATCH 10/12] Add options for spam count and interval --- modules/spamfilter/lang/en.php | 42 ++++++++++++------- modules/spamfilter/lang/ko.php | 27 ++++++------ .../spamfilter.admin.controller.php | 4 +- modules/spamfilter/spamfilter.model.php | 4 +- modules/spamfilter/tpl/config_block.html | 14 +++++++ 5 files changed, 60 insertions(+), 31 deletions(-) diff --git a/modules/spamfilter/lang/en.php b/modules/spamfilter/lang/en.php index 798b9bb3a..b46ca96cc 100644 --- a/modules/spamfilter/lang/en.php +++ b/modules/spamfilter/lang/en.php @@ -1,7 +1,10 @@ cmd_denied_ip = 'IP Address Blacklist'; -$lang->cmd_denied_word = 'Word Blacklist'; -$lang->spamfilter = 'Spam filter'; +$lang->cmd_denied_word = 'Keyword Blacklist'; +$lang->cmd_config_block = 'Automatic Blocking'; +$lang->add_denied_ip = 'Add IP address or range'; +$lang->add_denied_word = 'Add keyword'; +$lang->spamfilter = 'Spam Filter'; $lang->denied_ip = 'Blocked IP Address'; $lang->interval = 'Interval for spam filtering'; $lang->limit_count = 'No. of post limited'; @@ -10,22 +13,29 @@ $lang->word = 'Keyword'; $lang->hit = 'Hit'; $lang->latest_hit = 'Latest Hits'; $lang->about_interval = 'All articles attempted for posting within the assigned time will be blocked.'; -$lang->about_limit_count = 'If exceeded the posting limitation, - that IP will be regarded as a spam, thus will have limitations on posting articles, comments, and trackbacks.'; -$lang->about_denied_ip = 'You can add IP address range like 127.0.0.* by using *.'; -$lang->about_denied_word = 'When you add a word to Word Blacklist, - articles including it will be blocked.'; -$lang->about_check_trackback = 'A single IP per article is allowed for trackbacks.'; -$lang->msg_alert_limited_by_config = 'Posting an article within %s seconda is not allowed.\\n If you keep trying, your IP address will be blacklisted.'; -$lang->msg_alert_limited_message_by_config = 'sending an message within %s seconda is not allowed.\\n If you keep trying, your IP address will be blacklisted.'; -$lang->msg_alert_denied_word = 'The word "%s" is not allowed.'; -$lang->msg_alert_registered_denied_ip = 'Your IP address is blacklisted,\\n so you may have limitations on normal using of this site.\\n If you have any questions on that matter, please contact the site administrator.'; +$lang->about_denied_ip = 'Please enter one IP address (e.g. 127.0.0.1) or range (e.g. 127.0.0.0/24) per line. Comments may start with //.'; +$lang->about_denied_word = 'Please enter one keyword per line. Keywords may contain 2 to 40 characters.'; +$lang->msg_alert_limited_by_config = 'Please do not post repeatedly within %d seconds. If you keep trying, your IP address will be blocked.'; +$lang->msg_alert_limited_message_by_config = 'Please do not send messages repeatedly within %d seconds. If you keep trying, your IP address will be blocked.'; +$lang->msg_alert_denied_word = 'The word "%s" is not allowed on this site.'; +$lang->msg_alert_registered_denied_ip = 'Your IP address has been blocked for abuse. Please contact the administrator.'; $lang->msg_alert_trackback_denied = 'Only one trackback per an article is allowed.'; -$lang->cmd_interval = 'Do you want to blacklist the users who attempt to post articles more than 3 times for 10 seconds? The blacklisted users cannot write articles or comments and send trackbacks.'; -$lang->cmd_check_trackback = 'Do you want to blacklist the users who attempt to post more than 2 trackbacks to one article? The blacklisted users cannot post trackbacks.'; +$lang->cmd_interval = 'Block Post/Comment Spam'; +$lang->cmd_interval_help = 'Block IP addresses that post or comment too much in a short time. Blocked IP addresses will not be able to post, comment, or send messages.'; +$lang->cmd_check_trackback = 'Block Trackback Spam'; +$lang->cmd_check_trackback_help = 'Block IP addresses that send multiple trackbacks to the same document.
    This only works if the trackback module is installed.'; +$lang->cmd_limits_interval = 'Block Interval'; +$lang->cmd_limits_interval_help = 'Block IP addresses that post or comment too much within this number of seconds.'; +$lang->cmd_limits_count = 'Post/Comment Count'; +$lang->cmd_limits_count_help = 'Block IP addresses that post or comment this number of times within the above number of seconds.'; +$lang->cmd_ipv4_block_range = 'IPv4 Block Range'; +$lang->cmd_ipv6_block_range = 'IPv6 Block Range'; +$lang->cmd_block_range_self = 'single IP address only'; +$lang->cmd_block_range_help = 'This option allows you to block an entire range of IP addresses when a spammer is found.
    Caution: if you block an excessively wide range, you may also end up blocking innocent users.'; +$lang->cmd_block_range = 'IP addresses with the same %d last blocks'; +$lang->unit_write_count = 'times'; $lang->add = 'Add'; -$lang->yes = 'Yes'; -$lang->no = 'No'; $lang->msg_duplicate = 'Duplicate'; $lang->msg_invalid_ip = 'Invalid IP address format.'; $lang->msg_invalid_word = 'Spam keywords must be between 2 and 40 characters.'; +$lang->msg_faillist = '
    Error (already blocked)
    %s '; diff --git a/modules/spamfilter/lang/ko.php b/modules/spamfilter/lang/ko.php index 442f5f1aa..09c17244b 100644 --- a/modules/spamfilter/lang/ko.php +++ b/modules/spamfilter/lang/ko.php @@ -13,26 +13,29 @@ $lang->word = '키워드'; $lang->hit = '히트'; $lang->latest_hit = '최근 히트'; $lang->about_interval = '지정된 시간 내에 글을 등록하지 못하게 합니다.'; -$lang->about_limit_count = '지정된 시간 내에 제한수를 넘겨서 글 작성을 시도하면 스팸으로 인식, 해당 IP의 글 작성, 댓글 작성, 트랙백 발송, 쪽지 발송 등을 금지합니다.'; -$lang->about_denied_ip = '\'스팸 IP // 메모\' 형식으로 입력하세요. 여러개의 항목은 줄을 바꾸어 입력하세요.'; -$lang->about_denied_word = '여러개의 항목은 줄을 바꾸어 입력하세요. (2~40자)'; -$lang->about_check_trackback = '한 글에 한 IP에만 트랙백을 허용할 수 있습니다.'; -$lang->msg_alert_limited_by_config = '%s 초 이내에 글 작성은 금지 됩니다. 계속 시도하면 금지 IP에 등록될 수 있습니다.'; -$lang->msg_alert_limited_message_by_config = '%s 초 이내에 쪽지 발송은 금지 됩니다. 계속 시도하면 금지 IP에 등록될 수 있습니다.'; -$lang->msg_alert_denied_word = '"%s"는 사용 금지된 단어입니다.'; -$lang->msg_alert_registered_denied_ip = '금지 IP에 등록되어 정상적인 활동에 제한을 받게 됐습니다. 사이트 관리자에게 문의 바랍니다.'; +$lang->about_denied_ip = '한 줄에 하나씩 IP 주소(예: 127.0.0.1) 또는 대역(예: 127.0.0.0/24)을 입력하세요. // 뒷부분은 설명으로 저장됩니다. 예: 127.0.0.1 // 설명'; +$lang->about_denied_word = '한 줄에 하나씩 스팸 키워드를 입력하세요. (2~40자)'; +$lang->msg_alert_limited_by_config = '%d초 이내에 연속 글 작성은 금지됩니다. 계속 시도하면 IP가 차단될 수 있습니다.'; +$lang->msg_alert_limited_message_by_config = '%d초 이내에 연속 쪽지 발송은 금지됩니다. 계속 시도하면 IP가 차단될 수 있습니다.'; +$lang->msg_alert_denied_word = '"%s"은(는) 사용이 금지된 단어입니다.'; +$lang->msg_alert_registered_denied_ip = 'IP가 차단되었습니다. 사이트 관리자에게 문의 바랍니다.'; $lang->msg_alert_trackback_denied = '한 글에는 하나의 트랙백만 허용됩니다.'; $lang->cmd_interval = '글, 댓글 스팸 차단'; -$lang->cmd_interval_help = '10초 동안 3회 이상 글이나 댓글을 작성하면 스패머로 간주하고 글, 댓글 작성과 엮인글 발송, 쪽지 발송을 차단합니다.'; +$lang->cmd_interval_help = '아래에 지정한 시간 내에 다수의 글이나 댓글을 작성하면 스패머로 간주하고 글, 댓글 작성과 엮인글 발송, 쪽지 발송을 차단합니다.'; $lang->cmd_check_trackback = '트랙백 스팸 차단'; $lang->cmd_check_trackback_help = '하나의 글에 2회 이상 엮인글을 등록하면 스패머로 간주하고 엮인글을 차단합니다.
    트랙백 모듈이 설치되어 있는 경우에만 적용됩니다.'; +$lang->cmd_limits_interval = '글, 댓글 제한 시간'; +$lang->cmd_limits_interval_help = '지정한 시간 내에 아래의 갯수만큼 글이나 댓글을 작성하면 스패머로 간주합니다.'; +$lang->cmd_limits_count = '글, 댓글 작성 갯수'; +$lang->cmd_limits_count_help = '위에서 지정한 시간 내에 이 갯수만큼 글이나 댓글을 작성하면 스패머로 간주합니다.'; $lang->cmd_ipv4_block_range = 'IPv4 차단 범위'; $lang->cmd_ipv6_block_range = 'IPv6 차단 범위'; $lang->cmd_block_range_self = '해당 IP만 차단'; -$lang->cmd_block_range_help = '스패머 발견시 비슷한 대역의 IP를 한꺼번에 차단할 수 있습니다.
    지나치게 광범위하게 차단하면 정상적인 사용자에게 피해가 발생할 수 있으니 주의하시기 바랍니다.'; -$lang->cmd_block_range = '마지막 %s자리가 같은 IP를 모두 차단'; +$lang->cmd_block_range_help = '스패머 발견시 비슷한 대역의 IP를 한꺼번에 차단할 수 있습니다. 숫자가 작을수록 광범위하게 차단됩니다.
    지나치게 광범위하게 차단하면 정상적인 사용자에게 피해가 발생할 수 있으니 주의하시기 바랍니다.'; +$lang->cmd_block_range = '마지막 %d자리가 같은 IP를 모두 차단'; +$lang->unit_write_count = '회'; $lang->add = '추가'; $lang->msg_duplicate = '이미 존재합니다.'; $lang->msg_invalid_ip = 'IP 주소 형식이 올바르지 않습니다.'; $lang->msg_invalid_word = '스팸 키워드는 2~40자 사이여야 합니다.'; -$lang->msg_faillist = '
    실패(이미 존재합니다.)
    %s '; +$lang->msg_faillist = '
    실패 (이미 차단되어 있습니다)
    %s '; diff --git a/modules/spamfilter/spamfilter.admin.controller.php b/modules/spamfilter/spamfilter.admin.controller.php index 29cdc3fe7..df7fa8306 100644 --- a/modules/spamfilter/spamfilter.admin.controller.php +++ b/modules/spamfilter/spamfilter.admin.controller.php @@ -17,7 +17,7 @@ class spamfilterAdminController extends spamfilter function procSpamfilterAdminInsertConfig() { // Get the default information - $args = Context::gets('limits', 'check_trackback', 'ipv4_block_range', 'ipv6_block_range'); + $args = Context::gets('limits', 'limits_interval', 'limits_count', 'check_trackback', 'ipv4_block_range', 'ipv6_block_range'); // Set default values if ($args->limits != 'Y') @@ -36,6 +36,8 @@ class spamfilterAdminController extends spamfilter { $args->ipv6_block_range = ''; } + $args->limits_interval = intval($args->limits_interval); + $args->limits_count = intval($args->limits_count); // Create and insert the module Controller object $oModuleController = getController('module'); diff --git a/modules/spamfilter/spamfilter.model.php b/modules/spamfilter/spamfilter.model.php index 623b8714c..09be132dd 100644 --- a/modules/spamfilter/spamfilter.model.php +++ b/modules/spamfilter/spamfilter.model.php @@ -103,8 +103,8 @@ class spamfilterModel extends spamfilter $config = $this->getConfig(); if($config->limits != 'Y') return new Object(); - $limit_count = '3'; - $interval = '10'; + $limit_count = $config->limits_count ?: 3; + $interval = $config->limits_interval ?: 10; $count = $this->getLogCount($interval); diff --git a/modules/spamfilter/tpl/config_block.html b/modules/spamfilter/tpl/config_block.html index f1965cd17..1b85f0cbe 100644 --- a/modules/spamfilter/tpl/config_block.html +++ b/modules/spamfilter/tpl/config_block.html @@ -38,6 +38,20 @@

    {$lang->cmd_check_trackback_help}

    +
    + +
    + {$lang->unit_sec} +

    {$lang->cmd_limits_interval_help}

    +
    +
    +
    + +
    + {$lang->unit_write_count} +

    {$lang->cmd_limits_count_help}

    +
    +
    From b4d7d4e2c03d32c32b87676e3c453a4b0302dbca Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 23:03:17 +0900 Subject: [PATCH 11/12] Strip HTML and normalize spaces before checking text for blocked words --- modules/spamfilter/spamfilter.controller.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/spamfilter/spamfilter.controller.php b/modules/spamfilter/spamfilter.controller.php index 47200e00c..4916f1581 100644 --- a/modules/spamfilter/spamfilter.controller.php +++ b/modules/spamfilter/spamfilter.controller.php @@ -53,6 +53,7 @@ class spamfilterController extends spamfilter { $text = $obj->title . ' ' . $obj->content . ' ' . $obj->nick_name . ' ' . $obj->homepage . ' ' . $obj->tags; } + $text = utf8_trim(utf8_normalize_spaces(htmlspecialchars_decode(strip_tags($text)))); $output = $oFilterModel->isDeniedWord($text); if(!$output->toBool()) return $output; // Check the specified time beside the modificaiton time @@ -89,7 +90,6 @@ class spamfilterController extends spamfilter $output = $oFilterModel->isDeniedIP(); if(!$output->toBool()) return $output; // Check if there is a ban on the word - $text = ''; if($is_logged) { $text = $obj->content; @@ -98,6 +98,7 @@ class spamfilterController extends spamfilter { $text = $obj->content . ' ' . $obj->nick_name . ' ' . $obj->homepage; } + $text = utf8_trim(utf8_normalize_spaces(htmlspecialchars_decode(strip_tags($text)))); $output = $oFilterModel->isDeniedWord($text); if(!$output->toBool()) return $output; // If the specified time check is not modified From de1684cf884223c93ae570eecd270db1c911dedf Mon Sep 17 00:00:00 2001 From: Kijin Sung Date: Tue, 13 Dec 2016 23:10:12 +0900 Subject: [PATCH 12/12] Take placeholder text out of the textarea --- modules/spamfilter/lang/ko.php | 2 +- modules/spamfilter/tpl/denied_ip_list.html | 5 +++-- modules/spamfilter/tpl/denied_word_list.html | 5 +++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/spamfilter/lang/ko.php b/modules/spamfilter/lang/ko.php index 09c17244b..58bfbaab2 100644 --- a/modules/spamfilter/lang/ko.php +++ b/modules/spamfilter/lang/ko.php @@ -13,7 +13,7 @@ $lang->word = '키워드'; $lang->hit = '히트'; $lang->latest_hit = '최근 히트'; $lang->about_interval = '지정된 시간 내에 글을 등록하지 못하게 합니다.'; -$lang->about_denied_ip = '한 줄에 하나씩 IP 주소(예: 127.0.0.1) 또는 대역(예: 127.0.0.0/24)을 입력하세요. // 뒷부분은 설명으로 저장됩니다. 예: 127.0.0.1 // 설명'; +$lang->about_denied_ip = '한 줄에 하나씩 IP 주소 또는 대역을 입력하세요. "//" 또는 "#" 뒷부분은 설명으로 저장됩니다. 예: 127.0.0.1 //설명, 127.0.0.1 #설명
    IP 대역 표기법은 매뉴얼을 참고하십시오.'; $lang->about_denied_word = '한 줄에 하나씩 스팸 키워드를 입력하세요. (2~40자)'; $lang->msg_alert_limited_by_config = '%d초 이내에 연속 글 작성은 금지됩니다. 계속 시도하면 IP가 차단될 수 있습니다.'; $lang->msg_alert_limited_message_by_config = '%d초 이내에 연속 쪽지 발송은 금지됩니다. 계속 시도하면 IP가 차단될 수 있습니다.'; diff --git a/modules/spamfilter/tpl/denied_ip_list.html b/modules/spamfilter/tpl/denied_ip_list.html index 1dd83fb3c..26d1c664e 100644 --- a/modules/spamfilter/tpl/denied_ip_list.html +++ b/modules/spamfilter/tpl/denied_ip_list.html @@ -35,12 +35,13 @@
    -
    + - + +

    {$lang->about_denied_ip}

    diff --git a/modules/spamfilter/tpl/denied_word_list.html b/modules/spamfilter/tpl/denied_word_list.html index 579171f96..1a521141a 100644 --- a/modules/spamfilter/tpl/denied_word_list.html +++ b/modules/spamfilter/tpl/denied_word_list.html @@ -37,12 +37,13 @@
    -
    + - + +

    {$lang->about_denied_word}