__( 'There aren\'t plugins vulnerabilities', 'wpvulnerability' ), 'status' => 'good', 'badge' => array( 'label' => __( 'Security', 'wpvulnerability' ), 'color' => 'green', ), 'description' => sprintf( '

%s

', __( 'Shows possible vulnerabilities that exist in installed plugins.', 'wpvulnerability' ) ), 'actions' => '', 'test' => 'wpvulnerability_plugins', ); // Check if any plugin vulnerabilities were found. $wpvulnerability_test_plugins_counter = wpvulnerability_get_component_count( 'plugins' ); if ( $wpvulnerability_test_plugins_counter ) { $result['status'] = 'critical'; $result['label'] = sprintf( // translators: Number of plugins vulnerabilities. _n( 'There is %d plugin with vulnerabilities', 'There are %d plugins with vulnerabilities', $wpvulnerability_test_plugins_counter, 'wpvulnerability' ), $wpvulnerability_test_plugins_counter ); $result['badge']['color'] = 'red'; $result['description'] = sprintf( '

%1$s

%2$s', __( 'We\'ve detected potential vulnerabilities in installed plugins. Please check them and keep them updated.', 'wpvulnerability' ), wpvulnerability_html_plugins() ); // Add action links to update plugins. $result['actions'] .= sprintf( '

%s

', esc_url( is_multisite() ? network_admin_url( 'plugins.php' ) : admin_url( 'plugins.php' ) ), __( 'Update plugins', 'wpvulnerability' ) ); } return $result; } /** * Tests for vulnerabilities in installed themes. * * @since 2.0.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_themes() { // Define the initial test result values. $result = array( 'label' => __( 'There aren\'t themes vulnerabilities', 'wpvulnerability' ), 'status' => 'good', 'badge' => array( 'label' => __( 'Security', 'wpvulnerability' ), 'color' => 'green', ), 'description' => sprintf( '

%s

', __( 'Shows possible vulnerabilities that exist in installed themes.', 'wpvulnerability' ) ), 'actions' => '', 'test' => 'wpvulnerability_themes', ); // Check if any theme vulnerabilities were found. $wpvulnerability_test_themes_counter = wpvulnerability_get_component_count( 'themes' ); if ( $wpvulnerability_test_themes_counter ) { $result['status'] = 'critical'; $result['label'] = sprintf( // translators: Number of themes vulnerabilities. _n( 'There is %d theme with vulnerabilities', 'There are %d themes with vulnerabilities', $wpvulnerability_test_themes_counter, 'wpvulnerability' ), $wpvulnerability_test_themes_counter ); $result['badge']['color'] = 'red'; $result['description'] = sprintf( '

%1$s

%2$s', __( 'We\'ve detected potential vulnerabilities in installed themes. Please check them and keep them updated.', 'wpvulnerability' ), wpvulnerability_html_themes() ); // Add action links to update themes. $result['actions'] .= sprintf( '

%s

', esc_url( is_multisite() ? network_admin_url( 'themes.php' ) : admin_url( 'themes.php' ) ), __( 'Update themes', 'wpvulnerability' ) ); } return $result; } /** * Tests for vulnerabilities in core. * * @since 2.0.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_core() { // Define the initial test result values. $result = array( 'label' => __( 'There aren\'t WordPress vulnerabilities', 'wpvulnerability' ), 'status' => 'good', 'badge' => array( 'label' => __( 'Security', 'wpvulnerability' ), 'color' => 'green', ), 'description' => sprintf( '

%s

', __( 'Shows possible vulnerabilities existing in the WordPress core.', 'wpvulnerability' ) ), 'actions' => '', 'test' => 'wpvulnerability_core', ); // Check if any core vulnerabilities were found. $wpvulnerability_test_core_counter = wpvulnerability_get_component_count( 'core' ); if ( $wpvulnerability_test_core_counter ) { $result['status'] = 'critical'; $result['label'] = sprintf( // translators: Number of core vulnerabilities. _n( 'There is %d core vulnerability', 'There are %d core vulnerabilities', $wpvulnerability_test_core_counter, 'wpvulnerability' ), $wpvulnerability_test_core_counter ); $result['badge']['color'] = 'red'; $result['description'] = sprintf( '

%1$s

%2$s', __( 'We\'ve detected potential vulnerabilities in this WordPress installation. Please check them and keep your installation updated.', 'wpvulnerability' ), wpvulnerability_html_core() ); // Add action links to update WordPress. $result['actions'] .= sprintf( '

%s

', esc_url( is_multisite() ? network_admin_url( 'update-core.php' ) : admin_url( 'update-core.php' ) ), __( 'Update WordPress', 'wpvulnerability' ) ); } return $result; } /** * Tests for vulnerabilities in a specified software component. * * @since 3.5.0 * * @param string $software The type of software to test (php, apache, nginx, mariadb, mysql). * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_software( $software ) { $software_list = array( 'php' => __( 'PHP', 'wpvulnerability' ), 'apache' => __( 'Apache HTTPD', 'wpvulnerability' ), 'nginx' => __( 'Nginx', 'wpvulnerability' ), 'mariadb' => __( 'MariaDB', 'wpvulnerability' ), 'mysql' => __( 'MySQL', 'wpvulnerability' ), 'imagemagick' => __( 'ImageMagick', 'wpvulnerability' ), 'curl' => __( 'curl', 'wpvulnerability' ), 'memcached' => __( 'memcached', 'wpvulnerability' ), 'redis' => __( 'Redis', 'wpvulnerability' ), 'sqlite' => __( 'SQLite', 'wpvulnerability' ), ); if ( ! array_key_exists( $software, $software_list ) ) { return array( 'label' => __( 'Invalid software type', 'wpvulnerability' ), 'status' => 'error', 'badge' => array( 'label' => __( 'Error', 'wpvulnerability' ), 'color' => 'red', ), 'description' => sprintf( '

%s

', __( 'The specified software type is not valid.', 'wpvulnerability' ) ), 'actions' => '', 'test' => 'wpvulnerability_' . $software, ); } // Define the initial test result values. $result = array( // translators: name of the software. 'label' => sprintf( __( 'There aren\'t %s vulnerabilities', 'wpvulnerability' ), $software_list[ $software ] ), 'status' => 'good', 'badge' => array( 'label' => __( 'Security', 'wpvulnerability' ), 'color' => 'green', ), 'description' => sprintf( '

%s

', // translators: software with vulnerabilities. sprintf( __( 'Shows possible vulnerabilities existing in %s.', 'wpvulnerability' ), $software_list[ $software ] ) ), 'actions' => '', 'test' => 'wpvulnerability_' . $software, ); // Check if any vulnerabilities were found. $vulnerability_counter = wpvulnerability_get_component_count( $software ); if ( $vulnerability_counter ) { $result['status'] = 'critical'; $result['label'] = sprintf( // translators: Software and number of vulnerabilities. _n( 'There is %1$d %2$s vulnerability', 'There are %1$d %2$s vulnerabilities', $vulnerability_counter, 'wpvulnerability' ), $vulnerability_counter, $software_list[ $software ] ); $result['badge']['color'] = 'red'; $result['description'] = sprintf( '

%1$s

%2$s', // translators: software with vulnerabilities. sprintf( __( 'We\'ve detected potential vulnerabilities in %s. Please check them and keep your installation updated.', 'wpvulnerability' ), $software_list[ $software ] ), wpvulnerability_html_software( $software ) ); // Add specific action links if necessary. if ( 'php' === $software && function_exists( 'wp_get_update_php_url' ) && class_exists( 'WP_Site_Health' ) ) { $result['actions'] .= sprintf( '

%s

', esc_url( wp_get_update_php_url() ), __( 'How to update PHP', 'wpvulnerability' ) ); } } return $result; } /** * Tests for vulnerabilities in MySQL. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_mysql() { return wpvulnerability_test_software( 'mysql' ); } /** * Tests for vulnerabilities in MariaDB. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_mariadb() { return wpvulnerability_test_software( 'mariadb' ); } /** * Tests for vulnerabilities in Apache. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_apache() { return wpvulnerability_test_software( 'apache' ); } /** * Tests for vulnerabilities in Nginx. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_nginx() { return wpvulnerability_test_software( 'nginx' ); } /** * Tests for vulnerabilities in PHP. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_php() { return wpvulnerability_test_software( 'php' ); } /** * Tests for vulnerabilities in ImageMagick. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_imagemagick() { return wpvulnerability_test_software( 'imagemagick' ); } /** * Tests for vulnerabilities in curl. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_curl() { return wpvulnerability_test_software( 'curl' ); } /** * Tests for vulnerabilities in memcached. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_memcached() { return wpvulnerability_test_software( 'memcached' ); } /** * Tests for vulnerabilities in Redis. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_redis() { return wpvulnerability_test_software( 'redis' ); } /** * Tests for vulnerabilities in SQLite. * * @since 3.5.0 * * @return array{label: string, status: string, badge: array{label: string, color: string}, description: string, actions: string, test: string} Array with the results of the vulnerability test. */ function wpvulnerability_test_sqlite() { return wpvulnerability_test_software( 'sqlite' ); } /** * Adds vulnerability tests to the Health Check & Troubleshooting page. * * This function registers various vulnerability tests for different components of the site, such as * WordPress core, themes, plugins, PHP, Apache, Nginx, MariaDB, and MySQL, to the Site Health status page. * * @since 2.0.0 * * @param array $tests Array of current site status tests. * * @return array The updated array of site status tests. */ function wpvulnerability_tests( $tests ) { // Ensure the 'direct' key is a typed array before assigning test entries. if ( ! isset( $tests['direct'] ) || ! is_array( $tests['direct'] ) ) { $tests['direct'] = array(); } if ( wpvulnerability_analyze_filter( 'core' ) ) { // Add test for Core WordPress vulnerabilities. $tests['direct']['wpvulnerability_core'] = array( 'label' => __( 'WPVulnerability Core', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_core', ); } if ( wpvulnerability_analyze_filter( 'themes' ) ) { // Add test for Theme vulnerabilities. $tests['direct']['wpvulnerability_themes'] = array( 'label' => __( 'WPVulnerability Themes', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_themes', ); } if ( wpvulnerability_analyze_filter( 'plugins' ) ) { // Add test for Plugin vulnerabilities. $tests['direct']['wpvulnerability_plugins'] = array( 'label' => __( 'WPVulnerability Plugins', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_plugins', ); } if ( wpvulnerability_analyze_filter( 'php' ) ) { // Add test for PHP vulnerabilities. $tests['direct']['wpvulnerability_php'] = array( 'label' => __( 'WPVulnerability PHP', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_php', ); } if ( wpvulnerability_analyze_filter( 'apache' ) ) { // Add test for Apache vulnerabilities. $tests['direct']['wpvulnerability_apache'] = array( 'label' => __( 'WPVulnerability Apache HTTPD', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_apache', ); } if ( wpvulnerability_analyze_filter( 'nginx' ) ) { // Add test for Nginx vulnerabilities. $tests['direct']['wpvulnerability_nginx'] = array( 'label' => __( 'WPVulnerability Nginx', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_nginx', ); } if ( wpvulnerability_analyze_filter( 'mariadb' ) ) { // Add test for MariaDB vulnerabilities. $tests['direct']['wpvulnerability_mariadb'] = array( 'label' => __( 'WPVulnerability MariaDB', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_mariadb', ); } if ( wpvulnerability_analyze_filter( 'mysql' ) ) { // Add test for MySQL vulnerabilities. $tests['direct']['wpvulnerability_mysql'] = array( 'label' => __( 'WPVulnerability MySQL', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_mysql', ); } if ( wpvulnerability_analyze_filter( 'imagemagick' ) ) { // Add test for ImageMagick vulnerabilities. $tests['direct']['wpvulnerability_imagemagick'] = array( 'label' => __( 'WPVulnerability ImageMagick', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_imagemagick', ); } if ( wpvulnerability_analyze_filter( 'curl' ) ) { // Add test for curl vulnerabilities. $tests['direct']['wpvulnerability_curl'] = array( 'label' => __( 'WPVulnerability curl', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_curl', ); } if ( wpvulnerability_analyze_filter( 'memcached' ) ) { // Add test for memcached vulnerabilities. $tests['direct']['wpvulnerability_memcached'] = array( 'label' => __( 'WPVulnerability memcached', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_memcached', ); } if ( wpvulnerability_analyze_filter( 'redis' ) ) { // Add test for Redis vulnerabilities. $tests['direct']['wpvulnerability_redis'] = array( 'label' => __( 'WPVulnerability redis', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_redis', ); } if ( wpvulnerability_analyze_filter( 'sqlite' ) ) { // Add test for SQLite vulnerabilities. $tests['direct']['wpvulnerability_sqlite'] = array( 'label' => __( 'WPVulnerability sqlite', 'wpvulnerability' ), 'test' => 'wpvulnerability_test_sqlite', ); } return $tests; } // Adds the vulnerability tests to the site status tests. // Site Health exists since WordPress 5.2. Core loads the WP_Site_Health class // lazily (only inside site-health.php, health-check AJAX, and the dashboard // widget), long after init, so class_exists() cannot be used here: it would // always be false and the integration would never register. Registering // unconditionally is safe on every version - below 5.2 the // 'site_status_tests' filter simply never fires. add_filter( 'site_status_tests', 'wpvulnerability_tests' );