From da604c0b95dd653d0465624a4336b42019d3ec5c Mon Sep 17 00:00:00 2001 From: "Simonis, Matthias" Date: Tue, 19 Mar 2024 19:48:20 +0000 Subject: [PATCH] adds the antivirus scan for data * comments * pingbacks & trackbacks * posts --- PluginPage/FullScan/FullScanMenuPage.php | 2 +- PluginPage/OnDemandScan/OnDemandScan.php | 175 ++++++++++++++++++ .../WordpressGdataAntivirusMenuPage.php | 3 + Vaas/ScanClient.php | 112 ++++++++++- wordpress-gdata-antivirus.php | 4 +- 5 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 PluginPage/OnDemandScan/OnDemandScan.php diff --git a/PluginPage/FullScan/FullScanMenuPage.php b/PluginPage/FullScan/FullScanMenuPage.php index 9c60817..bf64878 100644 --- a/PluginPage/FullScan/FullScanMenuPage.php +++ b/PluginPage/FullScan/FullScanMenuPage.php @@ -339,7 +339,7 @@ public function FullScanMenu(): void settings_errors('wordpress_gdata_antivirus_options_full_scan_schedule_start'); settings_errors('wordpress_gdata_antivirus_options_full_scan_batch_size'); ?> -

VaaS Settings

+

Full Scan Settings

'', + 'client_secret' => '', + ]); + if (empty($options['client_id']) || empty($options['client_secret'])) { + return; + } + \add_action('init', [$this, 'SetupFields']); + \add_action('admin_menu', [$this, 'SetupMenu']); + } + + public function SetupFields(): void + { + \register_setting( + 'wordpress_gdata_antivirus_options_on_demand_scan', + 'wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled', + [ + 'type' => 'boolean', + 'default' => false + ] + ); + \register_setting( + 'wordpress_gdata_antivirus_options_on_demand_scan', + 'wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled', + [ + 'type' => 'boolean', + 'default' => false + ] + ); + \register_setting( + 'wordpress_gdata_antivirus_options_on_demand_scan', + 'wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled', + [ + 'type' => 'boolean', + 'default' => false + ] + ); + \register_setting( + 'wordpress_gdata_antivirus_options_on_demand_scan', + 'wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled', + [ + 'type' => 'boolean', + 'default' => false + ] + ); + \register_setting( + 'wordpress_gdata_antivirus_options_on_demand_scan', + 'wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled', + [ + 'type' => 'boolean', + 'default' => false + ] + ); + } + + public function SetupMenu(): void + { + \add_settings_section( + 'wordpress_gdata_antivirus_options_on_demand_scan', + esc_html__('OnDemand scans', 'wordpress-gdata-antivirus'), + [$this, 'wordpress_gdata_antivirus_options_on_demand_scans_text'], + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG + ); + + \add_settings_field( + 'wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled', + esc_html__('Media upload scan enabled', 'wordpress-gdata-antivirus'), + [$this, 'wordpress_gdata_antivirus_options_media_upload_scan_enabled_text'], + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG, + 'wordpress_gdata_antivirus_options_on_demand_scan' + ); + + \add_settings_field( + 'wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled', + esc_html__('Plugin upload scan enabled', 'wordpress-gdata-antivirus'), + [$this, 'wordpress_gdata_antivirus_options_plugin_upload_scan_enabled_text'], + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG, + 'wordpress_gdata_antivirus_options_on_demand_scan' + ); + + \add_settings_field( + 'wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled', + esc_html__('Comment scan enabled', 'wordpress-gdata-antivirus'), + [$this, 'wordpress_gdata_antivirus_options_comment_scan_enabled_text'], + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG, + 'wordpress_gdata_antivirus_options_on_demand_scan' + ); + + \add_settings_field( + 'wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled', + esc_html__('Pingback scan enabled', 'wordpress-gdata-antivirus'), + [$this, 'wordpress_gdata_antivirus_options_pingback_scan_enabled_text'], + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG, + 'wordpress_gdata_antivirus_options_on_demand_scan' + ); + + \add_settings_field( + 'wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled', + esc_html__('Post scan enabled', 'wordpress-gdata-antivirus'), + [$this, 'wordpress_gdata_antivirus_options_post_scan_enabled_text'], + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG, + 'wordpress_gdata_antivirus_options_on_demand_scan' + ); + + \add_submenu_page( + WORDPRESS_GDATA_ANTIVIRUS_MENU_SLUG, + 'OnDemandScan', + 'OnDemandScan', + 'manage_options', + WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG, + [$this, 'OnDemandScanMenu'] + ); + } + + public function wordpress_gdata_antivirus_options_on_demand_scans_text() + { + echo '

' . esc_html__('Here you can set options for the on demand scans', 'wordpress-gdata-antivirus') . '

'; + } + + public function wordpress_gdata_antivirus_options_media_upload_scan_enabled_text() + { + $mediaUploadScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled', false); + echo ''; + } + + public function wordpress_gdata_antivirus_options_plugin_upload_scan_enabled_text() + { + $pluginUploadScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled', false); + echo ''; + } + + public function wordpress_gdata_antivirus_options_comment_scan_enabled_text() + { + $commentScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled', false); + echo ''; + } + + public function wordpress_gdata_antivirus_options_pingback_scan_enabled_text() + { + $pingbackScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled', false); + echo ''; + } + + public function wordpress_gdata_antivirus_options_post_scan_enabled_text() + { + $postScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled', false); + echo ''; + } + + public function OnDemandScanMenu(): void + { +?> +

OnDenamns Scan Settings

+ + + +
+FindingsMenuPage = new FindingsMenuPage(); $this->FullScanMenuPage = new FullScanMenuPage($this->FindingsMenuPage); + $this->OnDemandScan = new OnDemandScan(); } public function SetupFileds(): void diff --git a/Vaas/ScanClient.php b/Vaas/ScanClient.php index d63c601..3d25007 100644 --- a/Vaas/ScanClient.php +++ b/Vaas/ScanClient.php @@ -7,6 +7,7 @@ use VaasSdk\VaasOptions; use VaasSdk\Message\Verdict; use Gdatacyberdefenseag\WordpressGdataAntivirus\Logging\WordpressGdataAntivirusPluginDebugLogger; +use GuzzleHttp\Psr7\Stream; if (!class_exists('ScanClient')) { class ScanClient @@ -24,12 +25,117 @@ public function __construct() ); $this->vaas->connect($this->clientCredentialsGrantAuthenticator->getToken()); - \add_filter('wp_handle_upload_prefilter', [$this, 'scanSingleFile']); - \add_filter('wp_handle_sideload_prefilter', [$this, 'scanSingleFile']); + $pluginUploadScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled', false); + $mediaUploadScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled', false); + // we don't need to add the filters if both plugin and media upload scan are disabled + if ($pluginUploadScanEnabled === true || $mediaUploadScanEnabled === true) { + \add_filter('wp_handle_upload_prefilter', [$this, 'scanSingleUpload']); + \add_filter('wp_handle_sideload_prefilter', [$this, 'scanSingleUpload']); + } + + $commentScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled', false); + $pingbackScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled', false); + // we don't need to add the filter if both comment and pingback scan are disabled + if ($commentScanEnabled === true || $pingbackScanEnabled === true) { + \add_filter('preprocess_comment', [$this, 'scanComment']); + } + + $postScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled', false); + if ($postScanEnabled === true) { + \add_filter('wp_insert_post_data', [$this, 'scanPost']); + } } - public function scanSingleFile($file) + public function scanPost($data, $postarr, $unsanitized_postarr) { + $data = \wp_unslash($unsanitized_postarr); + if (empty($data['post_content'])) { + return $data; + } + + $postScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled', false); + if ($postScanEnabled === false) { + return $data; + } + + if (empty($postdata['post_content'])) { + return $data; + } + + $postContent = \wp_unslash($postdata['post_content']); + $postContentFopen = fopen(sprintf('data://text/plain,%s', $postContent), 'r'); + rewind($postContentFopen); + $postDataStream = new Stream($postContentFopen); + + $verdict = $this->vaas->ForStream($postDataStream); + WordpressGdataAntivirusPluginDebugLogger::Log(var_export($verdict, true)); + if (\VaasSdk\Message\Verdict::MALICIOUS === $verdict->Verdict) { + WordpressGdataAntivirusPluginDebugLogger::Log('wordpress-gdata-antivirus: virus found in post'); + wp_die(__('virus found')); + } + return $postdata; + } + + public function scanComment($commentdata) + { + $commentScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled', false); + $pingbackScanEnabled = (bool)\get_option('wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled', false); + + $commentScanEnabled = \get_option('wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled', false); + if ($commentScanEnabled === false) { + return $commentdata; + } + + if (empty($commentdata['comment_content'])) { + return $commentdata; + } + + // if this is a comment and the comment scan is disabled, we don't need to scan the comment + // 'comment_type' - 'pingback', 'trackback', or empty for regular comments see: https://developer.wordpress.org/reference/hooks/preprocess_comment/ + if (empty($commentdata['comment_type']) && $commentScanEnabled === false) { + return $commentdata; + // if this is a pingback and the pingback scan is disabled, we don't need to scan the comment + } elseif (!empty($commentdata['comment_type']) && $pingbackScanEnabled === false) { + return $commentdata; + } + + $commendContent = \wp_unslash($commentdata['comment_content']); + $commendContentFopen = fopen(sprintf('data://text/plain,%s', $commendContent), 'r'); + rewind($commendContentFopen); + $commentDataStream = new Stream($commendContentFopen); + + $verdict = $this->vaas->ForStream($commentDataStream); + WordpressGdataAntivirusPluginDebugLogger::Log(var_export($verdict, true)); + if (\VaasSdk\Message\Verdict::MALICIOUS === $verdict->Verdict) { + WordpressGdataAntivirusPluginDebugLogger::Log('wordpress-gdata-antivirus: virus found in comment'); + wp_die(__('virus found')); + } + return $commentdata; + } + + public function scanSingleUpload($file) + { + $pluginUploadScanEnabled = \get_option('wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled', false); + $mediaUploadScanEnabled = \get_option('wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled', false); + + // when this is a plugin uplaod but the plugin upload scan is disabled, we don't need to scan the file + $isPluginUplad = false; + if (isset($_GET['action'])) { + if ($_GET['action'] === 'upload-plugin') { + $isPluginUplad = true; + if ($pluginUploadScanEnabled === false) { + return $file; + } + } + } + + // when this is a media upload (not a plugin upload) but the media upload scan is disabled, we don't need to scan the file + if ($isPluginUplad === false) { + if ($mediaUploadScanEnabled === false) { + return $file; + } + } + $verdict = $this->scanFile($file['tmp_name']); if (\VaasSdk\Message\Verdict::MALICIOUS === $verdict) { $file['error'] = __('virus found'); diff --git a/wordpress-gdata-antivirus.php b/wordpress-gdata-antivirus.php index f8c5cfd..fe89dd6 100644 --- a/wordpress-gdata-antivirus.php +++ b/wordpress-gdata-antivirus.php @@ -1,7 +1,7 @@