From 5d4756b87d3b19a83de59e74e1e4cf091c1eda36 Mon Sep 17 00:00:00 2001 From: safronik Date: Thu, 21 Oct 2021 13:22:36 +0500 Subject: [PATCH 01/11] Fix: Update to 3.5.0. #3 --- uniforce/lib/Cleantalk/USP/Common/State.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/Common/State.php b/uniforce/lib/Cleantalk/USP/Common/State.php index f152c08..41575ce 100644 --- a/uniforce/lib/Cleantalk/USP/Common/State.php +++ b/uniforce/lib/Cleantalk/USP/Common/State.php @@ -143,9 +143,6 @@ class State extends \Cleantalk\USP\Common\Storage{ 'cured' => array(), ), '2fa_keys' => array(), - - // Crunch - 'updated_to_350' => true, ); public $default_remote_calls = array( From 40beedf83fb3d1a3d146ed93a9f870dd62062340 Mon Sep 17 00:00:00 2001 From: Artem Davydov Date: Tue, 2 Nov 2021 12:30:28 +0500 Subject: [PATCH 02/11] Fix: if real ip is not defined. --- uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php index 4885bfd..7b2683c 100644 --- a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php +++ b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php @@ -42,7 +42,7 @@ public function check(){ $results = array(); - if( $this->is_login_page && ! $this->is_logged_in && $this->do_check ){ + if( $this->is_login_page && ! $this->is_logged_in && $this->do_check && isset( $this->ip_array['real'] ) ){ $block_time = 20 * 60; // 20 minutes $allowed_count = 2; From 3b76c24228cdf0872d35829446cd5d78d40b8a0c Mon Sep 17 00:00:00 2001 From: Artem Davydov Date: Tue, 2 Nov 2021 12:49:44 +0500 Subject: [PATCH 03/11] Fix: notice send logs if ip is empty. --- uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php index 7b2683c..1265c15 100644 --- a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php +++ b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php @@ -249,7 +249,7 @@ public static function send_log( $ct_key ){ 'datetime' => (string) $log[2], 'user_login' => null, 'event' => (string) $log[0], - 'auth_ip' => strpos( ':', $log[1] ) === false ? (int) sprintf( '%u', ip2long( $log[1] ) ) : (string) $log[1], + 'auth_ip' => !empty($log[1]) && strpos( ':', $log[1] ) === false ? (int) sprintf( '%u', ip2long( $log[1] ) ) : (string) $log[1], 'page_url' => (string) $log[3], 'event_runtime' => null, 'role' => null, @@ -260,7 +260,7 @@ public static function send_log( $ct_key ){ 'datetime' => (string) $log[2], 'user_login' => null, 'event' => (string) $log[0], - 'auth_ip' => strpos( ':', $log[1] ) === false ? (int) sprintf( '%u', ip2long( $log[1] ) ) : (string) $log[1], + 'auth_ip' => !empty($log[1]) && strpos( ':', $log[1] ) === false ? (int) sprintf( '%u', ip2long( $log[1] ) ) : (string) $log[1], 'page_url' => (string) $log[3], 'event_runtime' => null, 'role' => null, From 259be3108f8534e1a21b5907834db79870a74382 Mon Sep 17 00:00:00 2001 From: safronik Date: Tue, 23 Nov 2021 11:53:40 +0300 Subject: [PATCH 04/11] New: Scanner.Search regexp signatures. - Scanner\Helper::file__get_string_number_with_needle() - modified - Scanner\Scanner::file__scan__for_signatures() - modified --- uniforce/lib/Cleantalk/USP/Scanner/Helper.php | 35 ++++++++++++------ .../lib/Cleantalk/USP/Scanner/Scanner.php | 36 +++++++++---------- 2 files changed, 42 insertions(+), 29 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/Scanner/Helper.php b/uniforce/lib/Cleantalk/USP/Scanner/Helper.php index d37daac..780b817 100644 --- a/uniforce/lib/Cleantalk/USP/Scanner/Helper.php +++ b/uniforce/lib/Cleantalk/USP/Scanner/Helper.php @@ -241,16 +241,29 @@ static public function file__get_original($file_info) static function is_windows(){ return strpos(strtolower(php_uname('s')), 'windows') !== false ? true : false; } - - /** - * Returns number of string with a given char position - * - * @param string $haystack String to search in - * @param int $position Character position - * - * @return int String nubmer - */ - static function file__get_string_number_with_needle($haystack, $position){ - return count(explode(PHP_EOL, substr($haystack, 0, $position))); + + /** + * Returns number of string with a given char position + * + * @param string $file_path String to search in + * @param int $signature_body Character position + * @param bool $is_regexp Flag. Is signature is regular expression? + * + * @return int String number + */ + public static function file__get_string_number_with_needle($file_path, $signature_body, $is_regexp = false){ + $file = file( $file_path ); + $out = 0; + + foreach( $file as $number => $line ){ + if( + ( $is_regexp && preg_match( $signature_body, $line ) ) || + ( ! $is_regexp && strripos( $line, stripslashes( $signature_body ) ) !== false ) + ){ + $out = $number; + } + } + + return $out; } } \ No newline at end of file diff --git a/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php b/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php index 0f12c83..c0ef72f 100644 --- a/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php +++ b/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php @@ -329,24 +329,24 @@ static public function file__scan__for_signatures($root_path, $file_info, $signa $verdict = array(); foreach ((array)$signatures as $signature){ - switch ($signature['type']) { - - case 'FILE': - if($file_info['full_hash'] === $signature['body']){ - /** @todo Add new type FILE */ - $verdict['SIGNATURES'][1][] = $signature['id']; - } - break; - - case 'CODE_PHP': - $file_content = file_get_contents($root_path.$file_info['path']); - if(strripos($file_content, $signature['body']) !== false){ - $string_number = ScannerHelper::file__get_string_number_with_needle($file_content, strripos($file_content, $signature['body'])); - /** @todo Add new type CODE_PHP */ - $verdict['SIGNATURES'][$string_number][] = $signature['id']; - } - break; - } + + if( $signature['type'] === 'FILE' ){ + if( $file_info['full_hash'] === $signature['body'] ){ + $verdict['SIGNATURES'][1][] = $signature['id']; + } + } + + if( in_array( $signature['type'], array('CODE_PHP', 'CODE_JS', 'CODE_HTML' ) ) ) { + $file_content = file_get_contents( $root_path . $file_info['path'] ); + $is_regexp = preg_match( '/\/.*\//', $signature['body'] ); + if( + ( $is_regexp && preg_match( $signature['body'], $file_content ) ) || + ( ! $is_regexp && strripos( $file_content, stripslashes( $signature['body'] ) ) !== false ) + ){ + $line_number = ScannerHelper::file__get_string_number_with_needle( $file_info['path'], $signature['body'], $is_regexp ); + $verdict['SIGNATURES'][ $line_number ][] = $signature['id']; + } + } } $file_info['weak_spots'] = !empty($file_info['weak_spots']) ? json_decode($file_info['weak_spots'], true) : array(); From 09906d1a6dfef91065d43ac74bdb06532f04712c Mon Sep 17 00:00:00 2001 From: safronik Date: Wed, 24 Nov 2021 15:42:24 +0300 Subject: [PATCH 05/11] New: Firewall update. - Using multi curl to download files - Storing temporary firewall *.csv.zg files locally - Helper class extended --- uniforce/lib/Cleantalk/USP/Common/Helper.php | 135 +++++++++++++++++- .../Cleantalk/USP/Uniforce/Firewall/FW.php | 81 +++++++++-- 2 files changed, 197 insertions(+), 19 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/Common/Helper.php b/uniforce/lib/Cleantalk/USP/Common/Helper.php index ba4cf67..1368827 100644 --- a/uniforce/lib/Cleantalk/USP/Common/Helper.php +++ b/uniforce/lib/Cleantalk/USP/Common/Helper.php @@ -672,8 +672,49 @@ static public function http__get_data_from_remote_gz( $url ){ return $data; } - - public static function http__download_remote_file( $url, $tmp_folder ){ + + /** + * Wrapper for http_request + * Requesting HTTP response code for $url + * + * @param string $path + * + * @return array|mixed|string + */ + public static function get_data_from_local_gz( $path ){ + + if ( file_exists( $path ) ) { + + if ( is_readable( $path ) ) { + + $data = file_get_contents( $path ); + + if ( $data !== false ){ + + if( static::get_mime_type( $data, 'application/x-gzip' ) ){ + + if( function_exists('gzdecode') ) { + + $data = gzdecode( $data ); + + if ( $data !== false ){ + return $data; + }else + return array( 'error' => 'Can not unpack datafile'); + + }else + return array( 'error' => 'Function gzdecode not exists. Please update your PHP at least to version 5.4 ' . $data['error'] ); + }else + return array('error' => 'WRONG_REMOTE_FILE_MIME_TYPE'); + }else + return array( 'error' => 'Couldn\'t get data' ); + }else + return array( 'error' => 'File is not readable: ' . $path ); + }else + return array( 'error' => 'File doesn\'t exists: ' . $path ); + } + + public static function http__download_remote_file( $url, $tmp_folder ){ $result = self::http__request( $url, array(), 'get_file' ); @@ -692,8 +733,88 @@ public static function http__download_remote_file( $url, $tmp_folder ){ }else return $result; } - - /** + + /** + * Do multi curl requests. + * + * @param array $urls Array of URLs to requests + * @param string $write_to Path to the writing files dir + * + * @return array + * @psalm-suppress PossiblyUnusedMethod + */ + public static function http__download_remote_file__multi( $urls, $write_to = '' ) + { + if( ! is_array( $urls ) || empty( $urls ) ) { + return array( 'error' => 'CURL_MULTI: Parameter is not an array.' ); + } + + foreach( $urls as $url ) { + if( ! is_string( $url ) ) { + return array( 'error' => 'CURL_MULTI: Parameter elements must be strings.' ); + } + } + + $urls_count = count( $urls ); + $curl_arr = array(); + $master = curl_multi_init(); + + for($i = 0; $i < $urls_count; $i++) + { + $url =$urls[$i]; + $curl_arr[$i] = curl_init($url); + $opts = array( + CURLOPT_RETURNTRANSFER => true, + CURLOPT_CONNECTTIMEOUT_MS => 10000, + CURLOPT_FORBID_REUSE => true, + CURLOPT_USERAGENT => self::DEFAULT_USER_AGENT . '; ' . ( isset( $_SERVER['REMOTE_ADDR'] ) ? $_SERVER['REMOTE_ADDR'] : 'UNKNOWN_HOST' ), + CURLOPT_HTTPHEADER => array('Expect:'), // Fix for large data and old servers http://php.net/manual/ru/function.curl-setopt.php#82418 + CURLOPT_FOLLOWLOCATION => true, + CURLOPT_MAXREDIRS => 5, + ); + curl_setopt_array($curl_arr[$i], $opts); + curl_multi_add_handle($master, $curl_arr[$i]); + } + + do { + curl_multi_exec($master,$running); + // @ToDo place here sleep(500) to avoid possible CPU overusing + } while($running > 0); + + $results = array(); + + for($i = 0; $i < $urls_count; $i++) + { + $info = curl_getinfo($curl_arr[$i], CURLINFO_HTTP_CODE); + if( 200 == $info ) { + if( ! empty( $write_to ) && is_dir( $write_to ) && is_writable( $write_to ) ) { + $results[] = file_put_contents( $write_to . DS . self::getFilenameFromUrl( $urls[$i] ), curl_multi_getcontent( $curl_arr[$i] ) ) + ? 'success' + : 'error'; + } else { + $results[] = curl_multi_getcontent( $curl_arr[$i] ); + } + + } else { + $results[] = 'error'; + } + } + return $results; + } + + /** + * @param $url string + * + * @return string + */ + public static function getFilenameFromUrl( $url ) + { + $array = explode( '/', $url ); + return end( $array ); + } + + + /** * Gets every HTTP_ headers from $_SERVER * * If Apache web server is missing then making @@ -945,6 +1066,12 @@ static function buffer__parse__csv( $buffer ){ static function buffer__parse__nsv( $buffer ){ $buffer = str_replace( array( "\r\n", "\n\r", "\r", "\n" ), "\n", $buffer ); $buffer = explode( "\n", $buffer ); + foreach( $buffer as $key => &$value ){ + if( $value === '' ){ + unset( $buffer[ $key ] ); + } + } + unset( $value ); return $buffer; } diff --git a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/FW.php b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/FW.php index 742eceb..6eb3d9a 100644 --- a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/FW.php +++ b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/FW.php @@ -250,14 +250,27 @@ public static function update( $api_key ){ $url_count = Get::get( 'url_count' ); $current_file_num = Get::get( 'current_file_num' ); + $files = isset( State::getInstance()->fw_stats['updating_folder'] ) + ? glob( State::getInstance()->fw_stats['updating_folder'] . DS . '/*csv.gz' ) + : array(); + // Get multifiles if( ! $multifile_url ){ $result = self::update__get_multifiles( $api_key ); - usleep( 500000 ); - - if( empty( $result['error'] ) ){ - + if( ! empty( $result['error'] ) ){ + return $result; + } + + $update_folder = self::update__prepare_upd_dir( CT_USP_ROOT . DS . 'fw_files' ); + if( ! empty( $update_folder['error'] ) ){ + return $update_folder; + } + + State::getInstance()->fw_stats->updating_folder = CT_USP_ROOT . DS . 'fw_files'; + $download_files_result = Helper::http__download_remote_file__multi( $result['file_urls'], State::getInstance()->fw_stats->updating_folder ); + if( empty( $download_files_result['error'] ) ){ + State::getInstance()->fw_stats->updating = true; State::getInstance()->fw_stats->update_percent = 0; State::getInstance()->fw_stats->entries = 0; @@ -283,15 +296,16 @@ public static function update( $api_key ){ return $result; // Write to DB - }elseif( $current_file_num < $url_count ){ + }elseif( count( $files ) ){ - $url_file_to_wrtie = str_replace( 'multifiles', $current_file_num, $multifile_url ); - - $result = self::update__write_to_db( $url_file_to_wrtie ); - usleep( 500000 ); + $result = self::update__write_to_db( reset( $files ) ); if( empty( $result['error'] ) ){ - + + if( file_exists(reset($files)) ){ + unlink(reset($files)); + } + //Increment firewall entries State::getInstance()->fw_stats->entries += $result; State::getInstance()->fw_stats->update_percent = round( ( ( (int) $current_file_num + 1 ) / (int) $url_count ), 2) * 100; @@ -336,8 +350,43 @@ public static function update( $api_key ){ return $result; } } - - /** + + public static function update__prepare_upd_dir( $dir_name ){ + + global $spbc; + + if( $dir_name === '' ) { + return array( 'error' => 'FW dir can not be blank.' ); + } + + $dir_name .= DS; + + if( ! is_dir( $dir_name ) && ! mkdir( $dir_name ) ){ + + return ! is_writable( CT_USP_ROOT ) + ? array( 'error' => 'Can not to make FW dir. Low permissions: ' . fileperms( CT_USP_ROOT ) ) + : array( 'error' => 'Can not to make FW dir. Unknown reason.' ); + + } else { + $files = glob( $dir_name . '/*' ); + if( $files === false ){ + return array( 'error' => 'Can not find FW files.' ); + } + if( count( $files ) === 0 ){ + return (bool) file_put_contents( $dir_name . 'index.php', ' 'Can not delete the FW file: ' . $file ); + } + } + } + + return (bool) file_put_contents( $dir_name . 'index.php', ' $file_url, @@ -417,7 +468,7 @@ static public function update__get_multifiles( $spbc_key ){ */ public static function update__write_to_db( $file_url ){ - $data = Helper::http__get_data_from_remote_gz( $file_url ); + $data = Helper::get_data_from_local_gz( $file_url ); if ( ! Err::check() ) { From 2cfbae44c1ffebac6b34da75a9385610814a2c26 Mon Sep 17 00:00:00 2001 From: safronik Date: Mon, 29 Nov 2021 12:03:27 +0300 Subject: [PATCH 06/11] Fix: Firewall. Brute force protection module. --- uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php index 1265c15..4e2ef8a 100644 --- a/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php +++ b/uniforce/lib/Cleantalk/USP/Uniforce/Firewall/BFP.php @@ -163,9 +163,13 @@ public static function update_log( $fw_result ) { // Updating common firewall log if( is_array( $fw_result ) && $fw_result['status'] !== 'PASS' ){ parent::update_log( $fw_result ); -// return; + return; } - + + if( is_array( $fw_result ) && $fw_result['status'] !== 'DENY_BY_BFP' ){ + $fw_result = 'auth_failed'; + } + global $salt; $params_default = array( From ec09946e940b133776266e7b9749c78e44361136 Mon Sep 17 00:00:00 2001 From: safronik Date: Mon, 29 Nov 2021 13:20:28 +0300 Subject: [PATCH 07/11] Version: 3.6.0. --- uniforce/inc/common.php | 4 ++-- uniforce/index.php | 2 +- uniforce/version.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/uniforce/inc/common.php b/uniforce/inc/common.php index 9f778dc..c70272c 100644 --- a/uniforce/inc/common.php +++ b/uniforce/inc/common.php @@ -5,14 +5,14 @@ * * Sets all main constants * - * Version: 3.5.0 + * Version: 3.6.0 */ use Cleantalk\USP\Variables\Server; use Cleantalk\USP\Common\RemoteCalls; if( ! defined( 'SPBCT_PLUGIN' ) ) define( 'SPBCT_PLUGIN', 'uniforce' ); -if( ! defined( 'SPBCT_VERSION' ) ) define( 'SPBCT_VERSION', '3.5.0' ); +if( ! defined( 'SPBCT_VERSION' ) ) define( 'SPBCT_VERSION', '3.6.0' ); if( ! defined( 'SPBCT_AGENT' ) ) define( 'SPBCT_AGENT', SPBCT_PLUGIN . '-' . str_replace( '.', '', SPBCT_VERSION ) ); if( ! defined( 'SPBCT_USER_AGENT' ) ) define( 'SPBCT_USER_AGENT', 'Cleantalk-Security-Universal-Plugin/' . SPBCT_VERSION ); diff --git a/uniforce/index.php b/uniforce/index.php index 1a6df6a..24a8327 100644 --- a/uniforce/index.php +++ b/uniforce/index.php @@ -1,6 +1,6 @@ Date: Wed, 1 Dec 2021 13:57:32 +0300 Subject: [PATCH 08/11] Fix: From test. Typo in settings. --- uniforce/inc/settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniforce/inc/settings.php b/uniforce/inc/settings.php index deb9479..e07ea29 100644 --- a/uniforce/inc/settings.php +++ b/uniforce/inc/settings.php @@ -36,7 +36,7 @@ function usp_settings__show_fw_statistics( $out = '' ) ? date('M d Y H:i:s', $fw_stats->last_update) : 'never' ) . '
'; - echo 'Security FireWall contains: ' . ( $fw_stats->entries ? $fw_stats->entries : 'no' ). ' entires. ' + echo 'Security FireWall contains: ' . ( $fw_stats->entries ? $fw_stats->entries : 'no' ). ' entries. ' . ( State::getInstance()->fw_stats->updating ? 'Under updating now: ' . State::getInstance()->fw_stats->update_percent. '%' : '' ) . '
'; echo 'Security FireWall logs were sent: ' . ( $fw_stats->logs_sent_time From 23a9fa39c6db50737e214d78ca21efea4734c114 Mon Sep 17 00:00:00 2001 From: safronik Date: Wed, 1 Dec 2021 15:58:22 +0300 Subject: [PATCH 09/11] Fix: From test. Malware signatures downloading and processing. --- uniforce/lib/Cleantalk/USP/Common/Helper.php | 41 ++++++++++++++----- uniforce/lib/Cleantalk/USP/Common/Storage.php | 13 ++++-- uniforce/lib/Cleantalk/USP/Scanner/Helper.php | 24 +++++------ .../lib/Cleantalk/USP/Scanner/Scanner.php | 2 +- 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/uniforce/lib/Cleantalk/USP/Common/Helper.php b/uniforce/lib/Cleantalk/USP/Common/Helper.php index 1368827..9bbf3a8 100644 --- a/uniforce/lib/Cleantalk/USP/Common/Helper.php +++ b/uniforce/lib/Cleantalk/USP/Common/Helper.php @@ -1038,15 +1038,27 @@ static function get_mime_type( $data, $type = '' ) } return $type; } - - /** + + /** + * Pops line from the csv buffer and fromat it by map to array + * + * @param $csv + * @param array $map + * + * @return array|false + */ + public static function buffer__csv__get_map( &$csv ){ + $line = static::buffer__csv__pop_line( $csv ); + return explode( ',', $line ); + } + + /** * Parse Comma-separated values * * @param $buffer * * @return false|string[] */ - static function buffer__parse__csv( $buffer ){ $buffer = explode( "\n", $buffer ); $buffer = self::buffer__trim_and_clear_from_empty_lines( $buffer ); @@ -1082,11 +1094,11 @@ static function buffer__parse__nsv( $buffer ){ * * @return false|string */ - static public function buffer__csv__pop_line( &$csv ){ - $pos = strpos( $csv, "\n" ); - $first_line = substr( $csv, 0, $pos ); - $csv = substr_replace( $csv, '', 0, $pos + 1 ); - return $first_line; + public static function buffer__csv__pop_line( &$csv ){ + $pos = strpos( $csv, "\n" ); + $line = substr( $csv, 0, $pos ); + $csv = substr_replace( $csv, '', 0, $pos + 1 ); + return $line; } /** @@ -1097,10 +1109,19 @@ static public function buffer__csv__pop_line( &$csv ){ * * @return array|false */ - static public function buffer__csv__pop_line_to_array( &$csv, $map = array() ){ + static public function buffer__csv__pop_line_to_array( &$csv, $map = array(), $stripslashes = false ){ $line = trim( static::buffer__csv__pop_line( $csv ) ); - $line = str_getcsv( $line, ',', '\'' ); + $line = strpos( $line, '\'' ) === 0 + ? str_getcsv( $line, ',', '\'' ) + : explode( ',', $line ); + if( $stripslashes ){ + $line = array_map( function( $elem ){ + return stripslashes( $elem ); + }, + $line + ); + } if( $map ) $line = array_combine( $map, $line ); diff --git a/uniforce/lib/Cleantalk/USP/Common/Storage.php b/uniforce/lib/Cleantalk/USP/Common/Storage.php index 0bf516f..26aa075 100644 --- a/uniforce/lib/Cleantalk/USP/Common/Storage.php +++ b/uniforce/lib/Cleantalk/USP/Common/Storage.php @@ -84,8 +84,12 @@ protected function get($option_name) $out = isset( $$option_name ) ? $$option_name : array(); break; case 'csv': - $data = file_get_contents( $filename ); - $out = \Cleantalk\USP\Uniforce\Helper::buffer__csv__to_array( $data, $this->map ); + $out = array(); + $fd = fopen( $filename, 'r' ); + while( $line = fgetcsv( $fd, 2000, ',', '\'', '' ) ){ + $out[] = array_combine($this->map, $line); + } + fclose( $fd ); break; } } @@ -116,8 +120,9 @@ public function save() case 'csv': $fp = fopen( $filename, 'w' ); - foreach( $this->convertToArray() as $field ) - fputcsv( $fp, $field, ',', '\'' ); + foreach( $this->convertToArray() as &$field ){ + fputcsv( $fp, $field, ',', '\'' ); + } fclose( $fp ); break; } diff --git a/uniforce/lib/Cleantalk/USP/Scanner/Helper.php b/uniforce/lib/Cleantalk/USP/Scanner/Helper.php index 780b817..03a235d 100644 --- a/uniforce/lib/Cleantalk/USP/Scanner/Helper.php +++ b/uniforce/lib/Cleantalk/USP/Scanner/Helper.php @@ -59,21 +59,17 @@ static public function get_hashes__signature( $last_signature_update = 0 ) $data = gzdecode($gz_data); if($data !== false){ - - $lines = \Cleantalk\USP\Uniforce\Helper::buffer__parse__csv($data); - + + // Set map for file + $map = strpos( self::signatures_file_url, '_mapped' ) !== false + ? \Cleantalk\USP\Uniforce\Helper::buffer__csv__get_map( $data ) // Map from file + : array( 'id', 'name', 'body', 'type', 'attack_type', 'submitted', 'cci' ); // Default map + $out = array(); - foreach($lines as $line){ - $out[] = array( - 'id' => ! isset( $line[0] ) ? '' : $line[0], - 'name' => ! isset( $line[1] ) ? '' : $line[1], - 'body' => ! isset( $line[2] ) ? '' : stripcslashes( $line[2] ), - 'type' => ! isset( $line[3] ) ? '' : $line[3], - 'attack_type' => ! isset( $line[4] ) ? '' : $line[4], - 'submitted' => ! isset( $line[5] ) ? '' : $line[5], - 'cci' => ! isset( $line[6] ) ? '' : stripcslashes( $line[6] ), - ); - } + while( $data ){ + $out[] = \Cleantalk\USP\Uniforce\Helper::buffer__csv__pop_line_to_array( $data, $map, true ); + } + return $out; }else return array('error' => 'COULDNT_UNPACK'); diff --git a/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php b/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php index c0ef72f..bae5da6 100644 --- a/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php +++ b/uniforce/lib/Cleantalk/USP/Scanner/Scanner.php @@ -338,7 +338,7 @@ static public function file__scan__for_signatures($root_path, $file_info, $signa if( in_array( $signature['type'], array('CODE_PHP', 'CODE_JS', 'CODE_HTML' ) ) ) { $file_content = file_get_contents( $root_path . $file_info['path'] ); - $is_regexp = preg_match( '/\/.*\//', $signature['body'] ); + $is_regexp = preg_match( '/^\/.*\/$/', $signature['body'] ); if( ( $is_regexp && preg_match( $signature['body'], $file_content ) ) || ( ! $is_regexp && strripos( $file_content, stripslashes( $signature['body'] ) ) !== false ) From a56c14ed74aa0433160f74691705a7427b3c0c9f Mon Sep 17 00:00:00 2001 From: safronik Date: Thu, 2 Dec 2021 09:37:25 +0300 Subject: [PATCH 10/11] Fix: Send file for analysis. - Empty dangerous code. - PHP Warning. --- uniforce/lib/Cleantalk/USP/Common/API.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uniforce/lib/Cleantalk/USP/Common/API.php b/uniforce/lib/Cleantalk/USP/Common/API.php index 600ed11..6e98fba 100644 --- a/uniforce/lib/Cleantalk/USP/Common/API.php +++ b/uniforce/lib/Cleantalk/USP/Common/API.php @@ -483,7 +483,7 @@ static public function method__security_mscan_files($api_key, $file_path, $file, 'path_to_sfile' => $file_path, 'attached_sfile' => $file, 'md5sum_sfile' => $file_md5, - 'dangerous_code' => $weak_spots, + 'dangerous_code' => json_encode( $weak_spots ), ); $result = static::send_request($request); From 91dcd16977203feee6a1216a540cb4ed7c59e50c Mon Sep 17 00:00:00 2001 From: safronik Date: Thu, 2 Dec 2021 09:39:39 +0300 Subject: [PATCH 11/11] Fix: Actions with files. - Resetting actions and view handlers after an action performed. - Hiding spinner after an action performed. --- uniforce/js/ct_ajax.js | 10 ++++++++++ uniforce/js/table.js | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/uniforce/js/ct_ajax.js b/uniforce/js/ct_ajax.js index 620780c..1571663 100644 --- a/uniforce/js/ct_ajax.js +++ b/uniforce/js/ct_ajax.js @@ -59,6 +59,16 @@ class CTAJAX{ success( response ){ + // Hide spinner + if( this.spinner ){ + if( typeof this.spinner == 'function' ) + this.spinner(); + if( typeof this.spinner == 'object' ){ + this.spinner = jQuery( this.spinner ); + this.spinner.css('display', 'none'); + } + } + if( !! response.error ){ this.error( diff --git a/uniforce/js/table.js b/uniforce/js/table.js index 0fd4ce4..a7aaa5e 100644 --- a/uniforce/js/table.js +++ b/uniforce/js/table.js @@ -12,7 +12,9 @@ jQuery(document).ready(function(){ // TABLE BULK ACTIONS spbc_bulk_action = null; function spbc_tbl__bulk_actions__listen(){ - jQuery('.tbl-bulk_actions--apply').on('click', function(){ + jQuery('.tbl-bulk_actions--apply') + .off('click') + .on('click', function(){ if(!spbc_bulk_action && !confirm(spbc_TableData.warning_bulk)) return; @@ -36,7 +38,9 @@ function spbc_tbl__bulk_actions__listen(){ // TABLE ROW ACTIONS function spbc_tbl__row_actions__listen(){ - jQuery('.tbl-row_action--ajax').on('click', function(){ + jQuery('.tbl-row_action--ajax') + .off('click') + .on('click', function(){ console.log('spbc_tbl__row_actions__listen click'); var self = jQuery(this); var data = { @@ -79,6 +83,7 @@ function spbc_tbl__row_actions__callback( result, data, obj ){ obj.html(result.temp_html); setTimeout(function(){ obj.html(tmp).css({background: 'inherit'}).find('.column-primary .row-actions .tbl-row_action--'+data.add_action).remove(); + usp_showHide__listen(); },5000); } if(spbc_bulk_action) @@ -167,8 +172,12 @@ function spbc_tbl__sort__listen(){ // Shows/hides full text function usp_showHide__listen(){ - jQuery('.spbcShortText').on('mouseover', function(){ jQuery(this).next().show(); }) - jQuery('.spbcFullText').on('mouseout', function(){ jQuery(this).hide(); }); + jQuery('.spbcShortText') + .off('mouseover' ) + .on('mouseover', function(){ jQuery(this).next().show(); }); + jQuery('.spbcFullText') + .off('mouseout' ) + .on('mouseout', function(){ jQuery(this).hide(); }); } // Callback for TABLE SORT ACTIONS