From 548fc1baab59eea3f82c8211fd3390fe5bdcee99 Mon Sep 17 00:00:00 2001 From: Kevin Heise Date: Wed, 23 Oct 2024 08:29:39 +0000 Subject: [PATCH 01/12] add sha256 guid and detection when scan is malicious --- PluginPage/FullScan/FullScanMenuPage.php | 2 +- Vaas/ScanClient.php | 41 +++++++++++++----------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/PluginPage/FullScan/FullScanMenuPage.php b/PluginPage/FullScan/FullScanMenuPage.php index 99cafaa..8ef8f3e 100644 --- a/PluginPage/FullScan/FullScanMenuPage.php +++ b/PluginPage/FullScan/FullScanMenuPage.php @@ -274,7 +274,7 @@ public function scan_batch( array $files ): void { continue; } $scan_client = $this->scan_client; - if ($scan_client->scan_file($file) === \VaasSdk\Message\Verdict::MALICIOUS) { + if ($scan_client->scan_file($file)->Verdict === \VaasSdk\Message\Verdict::MALICIOUS) { $this->logger->debug('add to findings ' . $file); $this->findings->add($file); } diff --git a/Vaas/ScanClient.php b/Vaas/ScanClient.php index dbfe49c..21168a5 100644 --- a/Vaas/ScanClient.php +++ b/Vaas/ScanClient.php @@ -9,7 +9,9 @@ use VaasSdk\Authentication\ClientCredentialsGrantAuthenticator; use VaasSdk\Authentication\ResourceOwnerPasswordGrantAuthenticator; use VaasSdk\Exceptions\VaasInvalidStateException; +use VaasSdk\Message\VaasVerdict; use VaasSdk\Message\Verdict; +use VaasSdk\Message\VerdictResponse; use VaasSdk\VaasOptions as VaasParameters; if (! class_exists('ScanClient')) { @@ -102,11 +104,11 @@ public function scan_post( $data ) { $this->connect(); try { - $verdict = $this->vaas->ForStream($stream); + $vaas_verdict = $this->vaas->ForStream($stream); } catch (VaasInvalidStateException $e) { try { $this->reconnect(); - $verdict = $this->vaas->ForStream($stream); + $vaas_verdict = $this->vaas->ForStream($stream); } catch (\Exception $e) { $this->admin_notices->add_notice(esc_html__('virus scan failed', 'gdata-antivirus')); $this->logger->debug($e->getMessage()); @@ -117,11 +119,11 @@ public function scan_post( $data ) { $this->logger->debug($e->getMessage()); return $data; } - $this->logger->debug(var_export($verdict, true)); + $this->logger->debug(var_export($vaas_verdict->Verdict, true)); // phpcs:ignore - if (\VaasSdk\Message\Verdict::MALICIOUS === $verdict->Verdict) { + if (\VaasSdk\Message\Verdict::MALICIOUS === $vaas_verdict->Verdict) { $this->logger->debug('gdata-antivirus: virus found in post'); - wp_die(esc_html__('virus found', 'gdata-antivirus')); + wp_die(esc_html__("Virus found! - Detection: $vaas_verdict->Detection - SHA256: $vaas_verdict->Sha256 - Guid: $vaas_verdict->Guid", 'gdata-antivirus')); } return $data; } @@ -155,11 +157,11 @@ public function scan_comment( $commentdata ) { $stream = $this->file_system->get_resource_stream_from_string($commend_content); $this->connect(); try { - $verdict = $this->vaas->ForStream($stream); + $vaas_verdict = $this->vaas->ForStream($stream); } catch (VaasInvalidStateException $e) { try { $this->reconnect(); - $verdict = $this->vaas->ForStream($stream); + $vaas_verdict = $this->vaas->ForStream($stream); } catch (\Exception $e) { $this->admin_notices->add_notice(esc_html__('virus scan failed', 'gdata-antivirus')); $this->logger->debug($e->getMessage()); @@ -168,11 +170,11 @@ public function scan_comment( $commentdata ) { $this->admin_notices->add_notice(esc_html__('virus scan failed', 'gdata-antivirus')); $this->logger->debug($e->getMessage()); } - $this->logger->debug(var_export($verdict, true)); + $this->logger->debug(var_export($vaas_verdict->Verdict, true)); // phpcs:ignore - if (\VaasSdk\Message\Verdict::MALICIOUS === $verdict->Verdict) { + if (\VaasSdk\Message\Verdict::MALICIOUS === $vaas_verdict->Verdict) { $this->logger->debug('gdata-antivirus: virus found in comment'); - wp_die(esc_html__('virus found', 'gdata-antivirus')); + wp_die(esc_html__("Virus found! - Detection: $vaas_verdict->Detection - SHA256: $vaas_verdict->Sha256 - Guid: $vaas_verdict->Guid", 'gdata-antivirus')); } return $commentdata; } @@ -211,33 +213,34 @@ public function scan_single_upload( $file ) { } } - $verdict = $this->scan_file($file['tmp_name']); + $vaas_verdict = $this->scan_file($file['tmp_name']); + $verdict = $vaas_verdict->Verdict; if (\VaasSdk\Message\Verdict::MALICIOUS === $verdict) { - $file['error'] = __('virus found', 'gdata-antivirus'); + $file['error'] = __("Virus found! - Detection: $vaas_verdict->Detection - SHA256: $vaas_verdict->Sha256 - Guid: $vaas_verdict->Guid", 'gdata-antivirus'); } return $file; } - public function scan_file( $file_path ): Verdict { + public function scan_file( $file_path ): VaasVerdict { $this->connect(); try { - $verdict = $this->vaas->ForFile($file_path)->Verdict; + $vaas_verdict = $this->vaas->ForFile($file_path); } catch (VaasInvalidStateException $e) { try { $this->reconnect(); - $verdict = $this->vaas->ForFile($file_path)->Verdict; + $vaas_verdict = $this->vaas->ForFile($file_path); } catch (\Exception $e) { $this->logger->debug($e->getMessage()); - return Verdict::UNKNOWN; + return new VaasVerdict(new VerdictResponse); } } catch (\Exception $e) { $this->logger->debug($e->getMessage()); - return Verdict::UNKNOWN; + return new VaasVerdict(new VerdictResponse); } $this->logger->debug( - 'gdata-antivirus: verdict for file ' . $file_path . ': ' . var_export($verdict, true) + 'gdata-antivirus: verdict for file ' . $file_path . ': ' . var_export($vaas_verdict, true) ); - return $verdict; + return $vaas_verdict; } } } From b4a843cfb9aebcff808f7b40def7d02fd69b900d Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 12:47:40 +0000 Subject: [PATCH 02/12] adds the functonallity to reset the findings --- Infrastructure/Database/FindingsQuery.php | 13 +++++++++++ Infrastructure/Database/IFindingsQuery.php | 1 + PluginPage/Findings/FindingsMenuPage.php | 27 ++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/Infrastructure/Database/FindingsQuery.php b/Infrastructure/Database/FindingsQuery.php index 8b0858b..4619855 100644 --- a/Infrastructure/Database/FindingsQuery.php +++ b/Infrastructure/Database/FindingsQuery.php @@ -3,6 +3,7 @@ namespace Gdatacyberdefenseag\GdataAntivirus\Infrastructure\Database; use Psr\Log\LoggerInterface; +use wpdb; class FindingsQuery implements IFindingsQuery { private LoggerInterface $logger; @@ -93,6 +94,18 @@ public function delete( string $file ): void { ); } + public function delete_all(): void { + global $wpdb; + assert($wpdb instanceof wpdb); + + if (! $this->table_exists()) { + return; + } + $wpdb->query( + $wpdb->prepare('TRUNCATE TABLE %s', $this->get_table_name()) + ); + } + public function get_all(): array { global $wpdb; diff --git a/Infrastructure/Database/IFindingsQuery.php b/Infrastructure/Database/IFindingsQuery.php index c929028..0b07fef 100644 --- a/Infrastructure/Database/IFindingsQuery.php +++ b/Infrastructure/Database/IFindingsQuery.php @@ -5,6 +5,7 @@ interface IFindingsQuery extends IDatabase { public function add( string $file ): void; public function delete( string $file ): void; + public function delete_all(): void; public function get_all(): array; public function table_exists(): bool; public function count(): int; diff --git a/PluginPage/Findings/FindingsMenuPage.php b/PluginPage/Findings/FindingsMenuPage.php index cef79a5..cc608e9 100644 --- a/PluginPage/Findings/FindingsMenuPage.php +++ b/PluginPage/Findings/FindingsMenuPage.php @@ -37,6 +37,7 @@ public function __construct( add_action('admin_menu', array( $this, 'setup_menu' )); add_action('admin_post_delete_findings', array( $this, 'delete_findings' )); + add_action('admin_post_reset_findings', array( $this, 'reset_findings' )); } public function setup_menu(): void { @@ -55,6 +56,29 @@ public function validate_findings(): void { $this->findings->validate(); } + public function reset_findings(): void { + $this->logger->debug('FindingsMenuPage::reset_findings'); + if (! isset($_POST['gdata-antivirus-reset-findings-nonce'])) { + wp_die( + esc_html__('Invalid nonce specified', 'gdata-antivirus'), + esc_html__('Error', 'gdata-antivirus'), + array( + 'response' => intval(403), + ) + ); + } + if (! wp_verify_nonce(sanitize_key($_POST['gdata-antivirus-reset-findings-nonce']), 'gdata-antivirus-reset-findings')) { + wp_die( + esc_html__('Invalid nonce specified', 'gdata-antivirus'), + esc_html__('Error', 'gdata-antivirus'), + array( + 'response' => intval(403), + ) + ); + } + $this->findings->delete_all(); + } + public function delete_findings(): void { $this->logger->debug('FindingsMenuPage::delete_findings'); if (! isset($_POST['gdata-antivirus-delete-findings-nonce'])) { @@ -146,6 +170,9 @@ public function findings_list(): void { + + + Date: Wed, 23 Oct 2024 12:55:49 +0000 Subject: [PATCH 03/12] add a how-to rebuilding the plugin without always rebuilding the container --- Readme.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Readme.md b/Readme.md index a9bc40c..982c319 100644 --- a/Readme.md +++ b/Readme.md @@ -57,6 +57,15 @@ The devcontainer is configured to mount the source code into the containers. Thi Within the devcontainer it starts a wordpress-environment with `docker composer` within that you can even debug the code running directly in wordpress. +### How to rebuild within the container + +When you change code, it is not instantly put into the container because the directory that is actually mounted is the scoped-code directory. +When starting something bigger you can just set the mount-point in the ./compose.yml and the `/var/www/html/wp-content/plugins/gdata-antivirus` in the ./.vscode/launch.json to the working directory meaning `.` or full path `/workspaces/wordpress-gdata-antivirus`. + +Doing this, you still have to test your changes with the scoped code, so basically reset your changes and rebuild the container. + +To avoid rebuilding the container on every change you can also just run the ./.devcontainer/configureWordPress.sh script with the simple `source .devcontainer/configureWordPress.sh` command. This will run the scoper and restart the composed containers. + ## Disclaimer While this plugin enhances the security of your WordPress installation, no security measure is foolproof. Regular backups and other security best practices are still recommended to ensure the safety of your website. From 4bc5e0d72cf94d6327c0417b4a9501aadec48cce Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 13:17:32 +0000 Subject: [PATCH 04/12] provide a switch for a "live" development mode this changes the mount of the compose file and the mount point for the debugger. once switch all changes that you do are directly changed in the container aswell, so you don't have to run the scoper again and restart the compose. but please be aware you still have to test in scoped mode because that's what we release to the customers. --- Readme.md | 8 ++++++++ switch-live-develop-mode.sh | 19 +++++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 switch-live-develop-mode.sh diff --git a/Readme.md b/Readme.md index 982c319..2aeac04 100644 --- a/Readme.md +++ b/Readme.md @@ -66,6 +66,14 @@ Doing this, you still have to test your changes with the scoped code, so basical To avoid rebuilding the container on every change you can also just run the ./.devcontainer/configureWordPress.sh script with the simple `source .devcontainer/configureWordPress.sh` command. This will run the scoper and restart the composed containers. +### Switch to live development mode + +To switch to a mode, where your changes are directly affecting the running wordpress container we provide the switch-live-develop-mode.sh script. Running this the first time will change the .vscode/launch.json and compose.yml files, so that the code in the root folder is directly mounted into the container and the debugger also points to this code (if you have a debugger running you have to restart it once). + +When running this script within a running container, you have to run `source .devcontainer/configureWordPress.sh` once to start live mode and once when you switch back to scoped mode. + +Please do not commit the code while in live mode. Just run the script again and it will reset these changes. + ## Disclaimer While this plugin enhances the security of your WordPress installation, no security measure is foolproof. Regular backups and other security best practices are still recommended to ensure the safety of your website. diff --git a/switch-live-develop-mode.sh b/switch-live-develop-mode.sh new file mode 100644 index 0000000..a2f7ec5 --- /dev/null +++ b/switch-live-develop-mode.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +if grep --fixed-strings --quiet -- '- ./scoped-code/:/var/www/html/wp-content/plugins/gdata-antivirus:ro,cached' compose.yml; +then + sed --in-place=.bak 's#/scoped-code##g' compose.yml + echo "you are now in live development mode" +else + mv compose.yml.bak compose.yml + echo "you are now in scoped development mode, make sure to run 'source .devcontainer/configureWordPress.sh' after all your changes" +fi + +if grep --fixed-strings --quiet '"/var/www/html/wp-content/plugins/gdata-antivirus": "${workspaceFolder}/scoped-code",' .vscode/launch.json; +then + sed --in-place=.bak 's#/scoped-code##g' .vscode/launch.json + echo "you can now debug the root code" +else + mv .vscode/launch.json.bak .vscode/launch.json + echo "you can now debug the scoped code" +fi \ No newline at end of file From d6aade872d79dc572239364a6d1ecef5302c0754 Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 13:21:46 +0000 Subject: [PATCH 05/12] after the scoper install with dev dependencies --- scoper.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scoper.sh b/scoper.sh index fe1b5b8..50dc520 100644 --- a/scoper.sh +++ b/scoper.sh @@ -4,7 +4,7 @@ set -e rm -rf scoped-code/ composer install --no-dev php-scoper add-prefix --force -composer install --no-dev +composer install mv scoped-code/vendor/netresearch/jsonmapper/src/JsonMapper/Exception.php scoped-code/vendor/netresearch/jsonmapper/src/JsonMapper/JsonMapper_Exception.php mv scoped-code/vendor/netresearch/jsonmapper/src/JsonMapper.php scoped-code/vendor/netresearch/jsonmapper/src/JsonMapper/JsonMapper.php From 2e79ed719b8087aa1d1d256a57d8988e633bdbd2 Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 14:34:23 +0000 Subject: [PATCH 06/12] enable debug mode --- .gitignore | 3 ++- compose.yml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 49e8afa..03b3e8f 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,5 @@ test.sh gdata-antivirus.zip test.php scoped-code/ -/svn/ \ No newline at end of file +/svn/ +eicar* \ No newline at end of file diff --git a/compose.yml b/compose.yml index de6487e..8defe43 100644 --- a/compose.yml +++ b/compose.yml @@ -17,6 +17,7 @@ services: WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress WORDPRESS_TEST_DB_NAME: wordpress_test + WORDPRESS_DEBUG: true volumes: - ./scoped-code/:/var/www/html/wp-content/plugins/gdata-antivirus:ro,cached From f36e0a74672e8f5650e859273d33db70513cf051 Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 14:34:59 +0000 Subject: [PATCH 07/12] add a function to reset findings --- Infrastructure/Database/FindingsQuery.php | 2 +- PluginPage/Findings/FindingsMenuPage.php | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Infrastructure/Database/FindingsQuery.php b/Infrastructure/Database/FindingsQuery.php index 4619855..4112cc3 100644 --- a/Infrastructure/Database/FindingsQuery.php +++ b/Infrastructure/Database/FindingsQuery.php @@ -102,7 +102,7 @@ public function delete_all(): void { return; } $wpdb->query( - $wpdb->prepare('TRUNCATE TABLE %s', $this->get_table_name()) + $wpdb->prepare('TRUNCATE TABLE %i', $this->get_table_name()) ); } diff --git a/PluginPage/Findings/FindingsMenuPage.php b/PluginPage/Findings/FindingsMenuPage.php index cc608e9..62a9afa 100644 --- a/PluginPage/Findings/FindingsMenuPage.php +++ b/PluginPage/Findings/FindingsMenuPage.php @@ -77,6 +77,7 @@ public function reset_findings(): void { ); } $this->findings->delete_all(); + wp_redirect(admin_url()); } public function delete_findings(): void { From 69c777d2287b6da88878152e93ef20dcb43113e0 Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 14:37:02 +0000 Subject: [PATCH 08/12] catching the specific exceptions didn't work, so I this will now reconnect on every exception once the connection gets lost, because scanning 100 or more files takes its time and in between there is no ping in this version of the sdk. will be fixed with the full async version --- Vaas/ScanClient.php | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/Vaas/ScanClient.php b/Vaas/ScanClient.php index 21168a5..8adacf5 100644 --- a/Vaas/ScanClient.php +++ b/Vaas/ScanClient.php @@ -8,9 +8,7 @@ use VaasSdk\Vaas; use VaasSdk\Authentication\ClientCredentialsGrantAuthenticator; use VaasSdk\Authentication\ResourceOwnerPasswordGrantAuthenticator; -use VaasSdk\Exceptions\VaasInvalidStateException; use VaasSdk\Message\VaasVerdict; -use VaasSdk\Message\Verdict; use VaasSdk\Message\VerdictResponse; use VaasSdk\VaasOptions as VaasParameters; @@ -105,7 +103,7 @@ public function scan_post( $data ) { $this->connect(); try { $vaas_verdict = $this->vaas->ForStream($stream); - } catch (VaasInvalidStateException $e) { + } catch (\Exception $e) { try { $this->reconnect(); $vaas_verdict = $this->vaas->ForStream($stream); @@ -114,10 +112,6 @@ public function scan_post( $data ) { $this->logger->debug($e->getMessage()); return $data; } - } catch (\Exception $e) { - $this->admin_notices->add_notice(esc_html__('virus scan failed', 'gdata-antivirus')); - $this->logger->debug($e->getMessage()); - return $data; } $this->logger->debug(var_export($vaas_verdict->Verdict, true)); // phpcs:ignore @@ -158,7 +152,7 @@ public function scan_comment( $commentdata ) { $this->connect(); try { $vaas_verdict = $this->vaas->ForStream($stream); - } catch (VaasInvalidStateException $e) { + } catch (\Exception $e) { try { $this->reconnect(); $vaas_verdict = $this->vaas->ForStream($stream); @@ -166,9 +160,6 @@ public function scan_comment( $commentdata ) { $this->admin_notices->add_notice(esc_html__('virus scan failed', 'gdata-antivirus')); $this->logger->debug($e->getMessage()); } - } catch (\Exception $e) { - $this->admin_notices->add_notice(esc_html__('virus scan failed', 'gdata-antivirus')); - $this->logger->debug($e->getMessage()); } $this->logger->debug(var_export($vaas_verdict->Verdict, true)); // phpcs:ignore @@ -225,7 +216,7 @@ public function scan_file( $file_path ): VaasVerdict { $this->connect(); try { $vaas_verdict = $this->vaas->ForFile($file_path); - } catch (VaasInvalidStateException $e) { + } catch (\Exception $e) { try { $this->reconnect(); $vaas_verdict = $this->vaas->ForFile($file_path); @@ -233,9 +224,6 @@ public function scan_file( $file_path ): VaasVerdict { $this->logger->debug($e->getMessage()); return new VaasVerdict(new VerdictResponse); } - } catch (\Exception $e) { - $this->logger->debug($e->getMessage()); - return new VaasVerdict(new VerdictResponse); } $this->logger->debug( 'gdata-antivirus: verdict for file ' . $file_path . ': ' . var_export($vaas_verdict, true) From 9a0133bb1f090549f7a807464da1f7dd72ef171f Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 18:23:04 +0000 Subject: [PATCH 09/12] add detection and sha256 to the findings page --- Infrastructure/Database/DetectedFile.php | 7 ++++++ Infrastructure/Database/FindingsQuery.php | 14 +++++++---- Infrastructure/Database/IFindingsQuery.php | 2 +- PluginPage/Findings/FindingsMenuPage.php | 28 ++++++++++++++++++---- PluginPage/FullScan/FullScanMenuPage.php | 9 +++++-- 5 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 Infrastructure/Database/DetectedFile.php diff --git a/Infrastructure/Database/DetectedFile.php b/Infrastructure/Database/DetectedFile.php new file mode 100644 index 0000000..ae50c6e --- /dev/null +++ b/Infrastructure/Database/DetectedFile.php @@ -0,0 +1,7 @@ +get_charset_collate(); $sql = 'CREATE TABLE ' . $this->get_table_name() . ' ( file_path VARCHAR(512) NOT NULL, + detection VARCHAR(128) NOT NULL, + sha256 VARCHAR(64) NOT NULL, UNIQUE KEY file_path (file_path) )' . $charset_collate . ';'; require_once ABSPATH . 'wp-admin/includes/upgrade.php'; dbDelta($sql); wp_cache_set($this->get_table_name(), 'true', 'GdataAntivirus'); - } + } public function remove(): void { global $wpdb; @@ -65,7 +67,7 @@ public function table_exists(): bool { return false; } - public function add( string $file ): void { + public function add( DetectedFile $detected_file ): void { global $wpdb; if (! $this->table_exists()) { @@ -75,7 +77,11 @@ public function add( string $file ): void { try { $wpdb->insert( $this->get_table_name(), - array( 'file_path' => $file ) + array( + 'file_path' => $detected_file->path, + 'detection' => $detected_file->detection, + 'sha256' => $detected_file->sha256 + ) ); } catch (\Exception $e) { $this->logger->debug($e->getMessage()); @@ -113,7 +119,7 @@ public function get_all(): array { return array(); } return $wpdb->get_results( - $wpdb->prepare('SELECT file_path FROM %i', $this->get_table_name()), + $wpdb->prepare('SELECT file_path, detection, sha256 FROM %i', $this->get_table_name()), ARRAY_A ); } diff --git a/Infrastructure/Database/IFindingsQuery.php b/Infrastructure/Database/IFindingsQuery.php index 0b07fef..8016dec 100644 --- a/Infrastructure/Database/IFindingsQuery.php +++ b/Infrastructure/Database/IFindingsQuery.php @@ -3,7 +3,7 @@ namespace Gdatacyberdefenseag\GdataAntivirus\Infrastructure\Database; interface IFindingsQuery extends IDatabase { - public function add( string $file ): void; + public function add( DetectedFile $file ): void; public function delete( string $file ): void; public function delete_all(): void; public function get_all(): array; diff --git a/PluginPage/Findings/FindingsMenuPage.php b/PluginPage/Findings/FindingsMenuPage.php index 62a9afa..8a77781 100644 --- a/PluginPage/Findings/FindingsMenuPage.php +++ b/PluginPage/Findings/FindingsMenuPage.php @@ -132,9 +132,15 @@ public function findings_list(): void { - + File + + Detection + + + Sha256 + @@ -159,6 +165,16 @@ public function findings_list(): void { echo esc_html($finding['file_path']); ?> + + + + + + - - - + 'admin-post.php?action=delete_findings' + )); ?> - + 'admin-post.php?action=reset_findings' + )); ?> isDir()) { continue; } + if (str_contains($file_path->getPathname(), "eicar") === false) { + continue; + } $this->logger->debug($file_path->getPathname()); array_push($files, $file_path->getPathname()); if (count($files) >= $batch_size) { @@ -274,9 +278,10 @@ public function scan_batch( array $files ): void { continue; } $scan_client = $this->scan_client; - if ($scan_client->scan_file($file)->Verdict === \VaasSdk\Message\Verdict::MALICIOUS) { + $vaas_verdict = $scan_client->scan_file($file); + if ($vaas_verdict->Verdict === \VaasSdk\Message\Verdict::MALICIOUS) { $this->logger->debug('add to findings ' . $file); - $this->findings->add($file); + $this->findings->add(new DetectedFile($file, $vaas_verdict->Detection, $vaas_verdict->Sha256)); } } } finally { From 00d3d845bd1a26607826c5016594a30815b53f44 Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 18:26:30 +0000 Subject: [PATCH 10/12] add changelog --- Readme.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Readme.txt b/Readme.txt index 74b54f0..8edc3b9 100644 --- a/Readme.txt +++ b/Readme.txt @@ -56,6 +56,11 @@ While the released code is hosted on the WordPress svn, we develop the plugin on == Changelog == += 2.0.9 = +* bugfix: reconnect on long running scans +* add detection and sha256 name to upload detection +* add detection and sha256 to the findings page + = 2.0.8 = * bugfix: posts could not be saved From 3e6de9a9f2ad222cb5ac520c7db5364f17ae564d Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Wed, 23 Oct 2024 18:36:55 +0000 Subject: [PATCH 11/12] fix bug with scoping --- PluginPage/FullScan/FullScanMenuPage.php | 7 ++++--- Readme.md | 6 ++++++ scoper.inc.php | 3 ++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/PluginPage/FullScan/FullScanMenuPage.php b/PluginPage/FullScan/FullScanMenuPage.php index aea1c3f..55cdc3c 100644 --- a/PluginPage/FullScan/FullScanMenuPage.php +++ b/PluginPage/FullScan/FullScanMenuPage.php @@ -246,9 +246,10 @@ public function full_scan(): void { if ($file_path->isDir()) { continue; } - if (str_contains($file_path->getPathname(), "eicar") === false) { - continue; - } + // For testing purposes, we only scan files with eicar in the name + // if (str_contains($file_path->getPathname(), "eicar") === false) { + // continue; + // } $this->logger->debug($file_path->getPathname()); array_push($files, $file_path->getPathname()); if (count($files) >= $batch_size) { diff --git a/Readme.md b/Readme.md index 2aeac04..637a671 100644 --- a/Readme.md +++ b/Readme.md @@ -74,6 +74,12 @@ When running this script within a running container, you have to run `source .de Please do not commit the code while in live mode. Just run the script again and it will reset these changes. +### Running the cron + +If you want to run the cron event directly user this command. + +`docker exec --user www-data -it gdata-antivirus-app-1 bash -c "XDEBUG_CONFIG='client_port=9080 client_host=172.19.0.1' wp --debug cron event run gdatacyberdefenseag_antivirus_scan_batch"` + ## Disclaimer While this plugin enhances the security of your WordPress installation, no security measure is foolproof. Regular backups and other security best practices are still recommended to ensure the safety of your website. diff --git a/scoper.inc.php b/scoper.inc.php index b20da43..e528a95 100644 --- a/scoper.inc.php +++ b/scoper.inc.php @@ -126,7 +126,8 @@ static function (string $filePath, string $prefix, string $contents): string { "SplFileInfo", "WP_Filesystem_Direct", "WP_Filesystem_Base", - "GdataAntivirusPlugin" + "GdataAntivirusPlugin", + "wpdb" ], 'exclude-functions' => [ // 'mb_str_split', From c28bee6a70fc6bb1f52911d0ee37ec05eb0012aa Mon Sep 17 00:00:00 2001 From: PT-ATA No One Date: Mon, 4 Nov 2024 14:42:31 +0000 Subject: [PATCH 12/12] composer update --- composer.json | 8 +++--- composer.lock | 78 +++++++++++++++++++++++++-------------------------- 2 files changed, 43 insertions(+), 43 deletions(-) diff --git a/composer.json b/composer.json index 80e96cc..b835557 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,7 @@ "require": { "php": ">=8.1", "gdata/vaas": "9.0.5", - "illuminate/container": "^11.27" + "illuminate/container": "^11.30" }, "config": { "platform": { @@ -32,8 +32,8 @@ }, "require-dev": { "johnpbloch/wordpress": "6.6.2", - "phpunit/phpunit": "^11.2", - "wp-coding-standards/wpcs": "^3.0", + "phpunit/phpunit": "^11.4", + "wp-coding-standards/wpcs": "^3.1", "symfony/finder": "^7.1" } -} +} \ No newline at end of file diff --git a/composer.lock b/composer.lock index acf7233..2183891 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "22fb7cfa3bf9ea3a4e65d0cab626ab40", + "content-hash": "6dbc678bbb2da49ad0fe8a69d78735ca", "packages": [ { "name": "amphp/amp", @@ -635,16 +635,16 @@ }, { "name": "amphp/parallel", - "version": "v2.2.9", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/amphp/parallel.git", - "reference": "73d293f1fc4df1bebc3c4fce1432e82dd7032238" + "reference": "9777db1460d1535bc2a843840684fb1205225b87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/parallel/zipball/73d293f1fc4df1bebc3c4fce1432e82dd7032238", - "reference": "73d293f1fc4df1bebc3c4fce1432e82dd7032238", + "url": "https://api.github.com/repos/amphp/parallel/zipball/9777db1460d1535bc2a843840684fb1205225b87", + "reference": "9777db1460d1535bc2a843840684fb1205225b87", "shasum": "" }, "require": { @@ -707,7 +707,7 @@ ], "support": { "issues": "https://github.com/amphp/parallel/issues", - "source": "https://github.com/amphp/parallel/tree/v2.2.9" + "source": "https://github.com/amphp/parallel/tree/v2.3.0" }, "funding": [ { @@ -715,7 +715,7 @@ "type": "github" } ], - "time": "2024-03-24T18:27:44+00:00" + "time": "2024-09-14T19:16:14+00:00" }, { "name": "amphp/parser", @@ -1336,16 +1336,16 @@ }, { "name": "illuminate/container", - "version": "v11.27.2", + "version": "v11.30.0", "source": { "type": "git", "url": "https://github.com/illuminate/container.git", - "reference": "bc49d144a20b0d432e1ac812c9e056594b6c6480" + "reference": "06dfc614aff58384b28ba5ad191f6a02d6b192cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/illuminate/container/zipball/bc49d144a20b0d432e1ac812c9e056594b6c6480", - "reference": "bc49d144a20b0d432e1ac812c9e056594b6c6480", + "url": "https://api.github.com/repos/illuminate/container/zipball/06dfc614aff58384b28ba5ad191f6a02d6b192cb", + "reference": "06dfc614aff58384b28ba5ad191f6a02d6b192cb", "shasum": "" }, "require": { @@ -1383,11 +1383,11 @@ "issues": "https://github.com/laravel/framework/issues", "source": "https://github.com/laravel/framework" }, - "time": "2024-10-08T13:34:53+00:00" + "time": "2024-10-11T15:30:11+00:00" }, { "name": "illuminate/contracts", - "version": "v11.27.2", + "version": "v11.30.0", "source": { "type": "git", "url": "https://github.com/illuminate/contracts.git", @@ -3425,16 +3425,16 @@ }, { "name": "phpunit/phpunit", - "version": "11.4.1", + "version": "11.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7875627f15f4da7e7f0823d1f323f7295a77334e" + "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7875627f15f4da7e7f0823d1f323f7295a77334e", - "reference": "7875627f15f4da7e7f0823d1f323f7295a77334e", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e8e8ed1854de5d36c088ec1833beae40d2dedd76", + "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76", "shasum": "" }, "require": { @@ -3448,21 +3448,21 @@ "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0.6", + "phpunit/php-code-coverage": "^11.0.7", "phpunit/php-file-iterator": "^5.1.0", "phpunit/php-invoker": "^5.0.1", "phpunit/php-text-template": "^4.0.1", "phpunit/php-timer": "^7.0.1", "sebastian/cli-parser": "^3.0.2", "sebastian/code-unit": "^3.0.1", - "sebastian/comparator": "^6.1.0", + "sebastian/comparator": "^6.1.1", "sebastian/diff": "^6.0.2", "sebastian/environment": "^7.2.0", "sebastian/exporter": "^6.1.3", "sebastian/global-state": "^7.0.2", "sebastian/object-enumerator": "^6.0.1", "sebastian/type": "^5.1.0", - "sebastian/version": "^5.0.1" + "sebastian/version": "^5.0.2" }, "suggest": { "ext-soap": "To be able to generate mocks based on WSDL files" @@ -3505,7 +3505,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.1" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.3" }, "funding": [ { @@ -3521,7 +3521,7 @@ "type": "tidelift" } ], - "time": "2024-10-08T15:38:37+00:00" + "time": "2024-10-28T13:07:50+00:00" }, { "name": "sebastian/cli-parser", @@ -3695,16 +3695,16 @@ }, { "name": "sebastian/comparator", - "version": "6.1.0", + "version": "6.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d" + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa37b9e2ca618cb051d71b60120952ee8ca8b03d", - "reference": "fa37b9e2ca618cb051d71b60120952ee8ca8b03d", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", "shasum": "" }, "require": { @@ -3715,12 +3715,12 @@ "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^11.3" + "phpunit/phpunit": "^11.4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "6.2-dev" } }, "autoload": { @@ -3760,7 +3760,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1" }, "funding": [ { @@ -3768,7 +3768,7 @@ "type": "github" } ], - "time": "2024-09-11T15:42:56+00:00" + "time": "2024-10-31T05:30:08+00:00" }, { "name": "sebastian/complexity", @@ -4528,16 +4528,16 @@ }, { "name": "symfony/finder", - "version": "v7.1.4", + "version": "v7.1.6", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823" + "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d95bbf319f7d052082fb7af147e0f835a695e823", - "reference": "d95bbf319f7d052082fb7af147e0f835a695e823", + "url": "https://api.github.com/repos/symfony/finder/zipball/2cb89664897be33f78c65d3d2845954c8d7a43b8", + "reference": "2cb89664897be33f78c65d3d2845954c8d7a43b8", "shasum": "" }, "require": { @@ -4572,7 +4572,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.4" + "source": "https://github.com/symfony/finder/tree/v7.1.6" }, "funding": [ { @@ -4588,7 +4588,7 @@ "type": "tidelift" } ], - "time": "2024-08-13T14:28:19+00:00" + "time": "2024-10-01T08:31:23+00:00" }, { "name": "theseer/tokenizer", @@ -4709,15 +4709,15 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=8.1" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { "php": "8.2" }, "plugin-api-version": "2.6.0" -} \ No newline at end of file +}