diff --git a/inc/spbc-admin.php b/inc/spbc-admin.php index 5fc6db3cd..674367692 100644 --- a/inc/spbc-admin.php +++ b/inc/spbc-admin.php @@ -298,12 +298,15 @@ function spbc_plugin_list_show_vulnerability($plugin_file, $plugin_data, $_statu $do_show = ( isset($spbc->settings['vulnerability_check__enable_cron'], $spbc->settings['vulnerability_check__warn_on_modules_pages']) && $spbc->settings['vulnerability_check__enable_cron'] == true && - $spbc->settings['vulnerability_check__warn_on_modules_pages'] == true && - isset($plugin_data['slug']) // Only plugins which have slug (from wordpress catalog) need to check + $spbc->settings['vulnerability_check__warn_on_modules_pages'] == true ); if ($do_show) { - $plugin_slug = isset($plugin_data['slug']) ? $plugin_data['slug'] : sanitize_title($plugin_data['Name']); + // WP.org slug is often missing here (custom Plugin URI). Fall back to folder/textdomain. + $plugin_slug = VulnerabilityAlarm::getPluginSlug($plugin_data, $plugin_file); + if ( $plugin_slug === '' ) { + return; + } $plugin_version = ! empty($plugin_data['Version']) ? $plugin_data['Version'] : ''; $plugin_report = VulnerabilityAlarm::checkPluginVulnerabilityStatic($plugin_slug, $plugin_version); if ( $plugin_report instanceof \CleantalkSP\SpbctWP\VulnerabilityAlarm\Dto\PluginReport ) { diff --git a/lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/VulnerabilityAlarm.php b/lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/VulnerabilityAlarm.php index 2412b012d..d93eea3b0 100755 --- a/lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/VulnerabilityAlarm.php +++ b/lib/CleantalkSP/SpbctWP/VulnerabilityAlarm/VulnerabilityAlarm.php @@ -118,8 +118,8 @@ public static function getSafePlugins($plugins, $refresh_static_data_before = tr if ( $refresh_static_data_before ) { $plugins_to_cloud = []; // Prepare data to the cloud call - foreach ( $plugins as $plugin ) { - $verified_slug = static::getPluginSlug($plugin); + foreach ( $plugins as $plugin_file => $plugin ) { + $verified_slug = static::getPluginSlug($plugin, is_string($plugin_file) ? $plugin_file : ''); if ( !empty($verified_slug) ) { $plugin_name = is_array($plugin) ? (isset($plugin['name']) ? $plugin['name'] : (isset($plugin['Name']) ? $plugin['Name'] : $verified_slug)) @@ -155,8 +155,8 @@ public static function getSafePlugins($plugins, $refresh_static_data_before = tr static::$plugins = $plugins_reports_to_use; - foreach ( $plugins as $plugin ) { - $verified_slug = static::getPluginSlug($plugin); + foreach ( $plugins as $plugin_file => $plugin ) { + $verified_slug = static::getPluginSlug($plugin, is_string($plugin_file) ? $plugin_file : ''); $verified_version = static::getPluginVersion($plugin); if ( empty($verified_slug) ) { diff --git a/tests/lib/CleantalkSP/VulnerabilityAlarm/VulnerabilityAlarmTest.php b/tests/lib/CleantalkSP/VulnerabilityAlarm/VulnerabilityAlarmTest.php new file mode 100644 index 000000000..9ecf2e955 --- /dev/null +++ b/tests/lib/CleantalkSP/VulnerabilityAlarm/VulnerabilityAlarmTest.php @@ -0,0 +1,102 @@ + + */ + private function getAsePluginData() + { + return [ + 'Name' => 'Admin and Site Enhancements (ASE)', + 'PluginURI' => 'https://www.wpase.com/plugin-uri', + 'Version' => '8.8.3', + 'Description' => 'Easily enable enhancements.', + 'Author' => 'wpase.com', + 'TextDomain' => 'admin-site-enhancements', + ]; + } + + /** + * @test + */ + public function testGetPluginSlugUsesFolderWhenWordpressOrgSlugIsMissing() + { + $plugin_file = 'admin-site-enhancements/admin-site-enhancements.php'; + + $this->assertSame( + 'admin-site-enhancements', + VulnerabilityAlarm::getPluginSlug($this->getAsePluginData(), $plugin_file) + ); + } + + /** + * @test + */ + public function testGetPluginSlugDoesNotUseSanitizedPluginName() + { + $plugin_file = 'admin-site-enhancements/admin-site-enhancements.php'; + $slug = VulnerabilityAlarm::getPluginSlug($this->getAsePluginData(), $plugin_file); + + $this->assertNotSame(sanitize_title('Admin and Site Enhancements (ASE)'), $slug); + $this->assertSame('admin-site-enhancements', $slug); + } + + /** + * @test + */ + public function testCheckPluginVulnerabilityStaticMatchesFolderSlugWithoutWpOrgSlug() + { + $report = new PluginReport(); + $report->id = '19615'; + $report->slug = 'admin-site-enhancements'; + $report->app_status = 'vulnerable'; + $report->CVE = 'CVE-2026-19615'; + $report->rs_app_version_max = '9.0.1'; + + $list = new ApiResults(); + $list->plugins = [$report]; + update_option(VulnerabilityAlarm::VULNERABILITY_LIST, $list, false); + + $plugin_file = 'admin-site-enhancements/admin-site-enhancements.php'; + $plugin_data = $this->getAsePluginData(); + $slug = VulnerabilityAlarm::getPluginSlug($plugin_data, $plugin_file); + $found = VulnerabilityAlarm::checkPluginVulnerabilityStatic($slug, $plugin_data['Version']); + + $this->assertInstanceOf(PluginReport::class, $found); + $this->assertSame('admin-site-enhancements', $found->slug); + $this->assertSame('CVE-2026-19615', $found->CVE); + } + + /** + * @test + */ + public function testIsModuleVersionMatchesReportDetectsVulnerableVersion() + { + $report = new PluginReport(); + $report->rs_app_version_max = '9.0.1'; + + $this->assertTrue(VulnerabilityAlarmService::isModuleVersionMatchesReport($report, '8.8.3')); + $this->assertFalse(VulnerabilityAlarmService::isModuleVersionMatchesReport($report, '9.0.1')); + $this->assertFalse(VulnerabilityAlarmService::isModuleVersionMatchesReport($report, '9.0.2')); + } +}