Skip to content

Commit

Permalink
Merge pull request #9 from GDATASoftwareAG/4-add-scanning-for-content…
Browse files Browse the repository at this point in the history
…-comments-pingbacks

4 add scanning for content comments pingbacks
  • Loading branch information
unglaublicherdude authored Mar 21, 2024
2 parents 6ba13ed + da604c0 commit 6506392
Show file tree
Hide file tree
Showing 5 changed files with 291 additions and 10 deletions.
7 changes: 2 additions & 5 deletions PluginPage/FullScan/FullScanMenuPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
use Gdatacyberdefenseag\WordpressGdataAntivirus\Logging\WordpressGdataAntivirusPluginDebugLogger;
use WP;

define('WORDPRESS_GDATA_ANTIVIRUS_MENU_FULL_SCAN_SLUG', WORDPRESS_GDATA_ANTIVIRUS_MENU_SLUG . '-findings');
define('WORDPRESS_GDATA_ANTIVIRUS_MENU_FULL_SCAN_SLUG', WORDPRESS_GDATA_ANTIVIRUS_MENU_SLUG . '-full-scan');
define('WORDPRESS_GDATA_ANTIVIRUS_MENU_FULL_SCAN_OPERATIONS_TABLE_NAME', 'WORDPRESS_GDATA_ANTIVIRUS_MENU_FULL_SCAN_OPERATIONS');

if (!class_exists('FullScanMenuPage')) {
Expand Down Expand Up @@ -299,9 +299,6 @@ public function FullScan(): void
if ($filePath->isDir()) {
continue;
}
if (!str_contains($filePath->getPathname(), "sentry")) {
continue;
}
WordpressGdataAntivirusPluginDebugLogger::Log($filePath->getPathname());
\array_push($files, $filePath->getPathname());
if (count($files) >= $batchSize) {
Expand Down Expand Up @@ -342,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');
?>
<h2>VaaS Settings</h2>
<h2>Full Scan Settings</h2>
<form action="options.php" method="post">
<?php
\settings_fields('wordpress_gdata_antivirus_options_full_scan_run');
Expand Down
175 changes: 175 additions & 0 deletions PluginPage/OnDemandScan/OnDemandScan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
<?php

namespace Gdatacyberdefenseag\WordpressGdataAntivirus\PluginPage\OnDemandScan;

define('WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG', WORDPRESS_GDATA_ANTIVIRUS_MENU_SLUG . '-on-demand-scan');

if (!class_exists('OnDemandScan')) {
class OnDemandScan
{
public function __construct()
{
$options = \get_option('wordpress_gdata_antivirus_options_credentials', [
'client_id' => '',
'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 '<p>' . esc_html__('Here you can set options for the on demand scans', 'wordpress-gdata-antivirus') . '</p>';
}

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 '<input type="checkbox" id="wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled" name="wordpress_gdata_antivirus_options_on_demand_scan_media_upload_scan_enabled" ' . \checked(true, $mediaUploadScanEnabled, false) . '>';
}

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 '<input type="checkbox" id="wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled" name="wordpress_gdata_antivirus_options_on_demand_scan_plugin_upload_scan_enabled" ' . \checked(true, $pluginUploadScanEnabled, false) . '>';
}

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 '<input type="checkbox" id="wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled" name="wordpress_gdata_antivirus_options_on_demand_scan_comment_scan_enabled" ' . \checked(true, $commentScanEnabled, false) . '>';
}

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 '<input type="checkbox" id="wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled" name="wordpress_gdata_antivirus_options_on_demand_scan_pingback_scan_enabled" ' . \checked(true, $pingbackScanEnabled, false) . '>';
}

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 '<input type="checkbox" id="wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled" name="wordpress_gdata_antivirus_options_on_demand_scan_post_scan_enabled" ' . \checked(true, $postScanEnabled, false) . '>';
}

public function OnDemandScanMenu(): void
{
?>
<h2>OnDenamns Scan Settings</h2>
<form action="options.php" method="post">
<?php
settings_fields('wordpress_gdata_antivirus_options_on_demand_scan');
do_settings_sections(WORDPRESS_GDATA_ANTIVIRUS_MENU_ON_DEMAND_SCAN_SLUG);
?>
<input name="submit" class="button button-primary" type="submit" value="<?php \esc_attr_e('Save', 'wordpress-gdata-antivirus'); ?>" />
</form>
<?php
}
}
}
3 changes: 3 additions & 0 deletions PluginPage/WordpressGdataAntivirusMenuPage.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Gdatacyberdefenseag\WordpressGdataAntivirus\PluginPage\Findings\FindingsMenuPage;
use Gdatacyberdefenseag\WordpressGdataAntivirus\PluginPage\FullScan\FullScanMenuPage;
use Gdatacyberdefenseag\WordpressGdataAntivirus\PluginPage\OnDemandScan\OnDemandScan;

define('WORDPRESS_GDATA_ANTIVIRUS_MENU_SLUG', 'wordpress-gdata-antivirus-menu');

Expand All @@ -12,6 +13,7 @@ class WordpressGdataAntivirusMenuPage
{
public FullScanMenuPage $FullScanMenuPage;
public FindingsMenuPage $FindingsMenuPage;
public OnDemandScan $OnDemandScan;

public function __construct()
{
Expand All @@ -20,6 +22,7 @@ public function __construct()

$this->FindingsMenuPage = new FindingsMenuPage();
$this->FullScanMenuPage = new FullScanMenuPage($this->FindingsMenuPage);
$this->OnDemandScan = new OnDemandScan();
}

public function SetupFileds(): void
Expand Down
112 changes: 109 additions & 3 deletions Vaas/ScanClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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');
Expand Down
4 changes: 2 additions & 2 deletions wordpress-gdata-antivirus.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php

/**
* wordpress-gdata-antivirus
* G DATA Antivirus
*
* @category Security
* @package GD_Scan
Expand All @@ -10,7 +10,7 @@
* @link https://github.com/GDATASoftwareAG/vaas
*
* @wordpress-plugin
* Plugin Name: wordpress-gdata-antivirus
* Plugin Name: G DATA Antivirus
* Version: 0.0.1
* Requires PHP: 8.1
* Plugin URI: https://github.com/GDATASoftwareAG/wordpress-gdata-antivirus
Expand Down

0 comments on commit 6506392

Please sign in to comment.