File: /home/emerlux/public_html/wp-content/plugins/wpvulnerability/wpvulnerability-core.php
<?php
/**
* Core functions
*
* @package WPVulnerability
*
* @version 2.0.0
*/
defined( 'ABSPATH' ) || die( 'No script kiddies please!' );
/**
* Adds a vulnerability notice under vulnerable core.
*
* @since 2.0.0
*
* @return void
*/
function wpvulnerability_core_info_after() {
// Retrieve the vulnerabilities for core from the options table and decode the JSON.
if ( is_multisite() ) {
$core_vulnerabilities = json_decode( get_site_option( 'wpvulnerability-core' ), true );
} else {
$core_vulnerabilities = json_decode( get_option( 'wpvulnerability-core' ), true );
}
// Generate the vulnerability notice message.
$message = sprintf(
/* translators: 1: core version */
__( 'WordPress %1$s has a known vulnerability that may be affecting this version.', 'wpvulnerability' ),
get_bloginfo( 'version' )
);
$information = '<p class="text-red"><img src="' . esc_url( WPVULNERABILITY_PLUGIN_URL ) . 'assets/logo16.png" style="height: 16px; vertical-align: text-top; width: 16px;" alt="" title="WPVulnerability"> <strong>' . $message . '</strong></p>';
$information .= '<table class="wp-list-table widefat wpvulnerability">';
// Loop through all vulnerabilities for the current version and add their details to the table row HTML markup.
if ( is_array( $core_vulnerabilities ) ) {
foreach ( $core_vulnerabilities as $vulnerability ) {
$what = array();
if ( isset( $vulnerability['impact']['cwe'] ) ) {
foreach ( $vulnerability['impact']['cwe'] as $vulnerability_cwe ) {
$what[] = '<div><b>' . wp_kses( (string) $vulnerability_cwe['name'], 'strip' ) . '</b></div><div><i>' . wp_kses_post( (string) $vulnerability_cwe['description'] ) . '</i></div>';
}
}
$sources = array();
if ( isset( $vulnerability['source'] ) ) {
foreach ( $vulnerability['source'] as $vulnerability_source ) {
$sources[] = '<a href="' . esc_url_raw( (string) $vulnerability_source['link'] ) . '" target="_blank" rel="external nofollow noopener noreferrer">[+]</a> ' . wp_kses( (string) $vulnerability_source['name'], 'strip' );
}
}
$source = count( $sources ) ? '<div style="padding-bottom: 5px;">' . implode( '<br>', $sources ) . '</div>' : '';
$score = isset( $vulnerability['impact']['cvss']['score'] ) ? number_format( (float) $vulnerability['impact']['cvss']['score'], 1, '.', '' ) : null;
$severity = isset( $vulnerability['impact']['cvss']['severity'] ) ? wpvulnerability_severity( $vulnerability['impact']['cvss']['severity'] ) : null;
$information .= '<tr>';
$information .= '<td style="max-width: 256px; min-width: 96px;">WordPress <b>' . wp_kses( (string) $vulnerability['name'], 'strip' ) . '</b></td>';
$information .= '<td>';
if ( count( $what ) ) {
$information .= '<div style="padding-bottom: 5px;">' . implode( '', $what ) . '</div>';
}
if ( ! is_null( $score ) || ! is_null( $severity ) ) {
$information .= '<div style="padding-bottom: 5px;">';
if ( ! is_null( $score ) ) {
$information .= '<div>' . __( 'Global score: ', 'wpvulnerability' ) . $score . ' / 10</div>';
}
if ( ! is_null( $severity ) ) {
$information .= '<div>' . __( 'Severity: ', 'wpvulnerability' ) . $severity . '</div>';
}
$information .= '</div>';
}
$information .= wp_kses( (string) $source, 'post' );
$information .= '</td>';
$information .= '</tr>';
}
}
$information .= '</table>';
echo $information; // phpcs:ignore
}
/**
* Retrieves vulnerabilities for a given WordPress core version and updates its data.
*
* @since 2.0.0
*
* @return array|false The updated core data array or false if no vulnerabilities are found.
*/
function wpvulnerability_get_fresh_core_vulnerabilities() {
// Get the core version and sanitize it.
$version = wpvulnerability_sanitize_version( get_bloginfo( 'version' ) );
// Retrieve vulnerabilities for the core version.
$response = wpvulnerability_get_core( $version, 0 );
$core_data = array();
// If no vulnerabilities are found, return false.
if ( empty( $response ) ) {
return false;
}
// If vulnerabilities are found, update the core data.
foreach ( $response as $v ) {
if ( isset( $v['name'], $v['source'], $v['impact'] ) ) { // Ensure expected keys exist.
$core_data[] = array(
'name' => wp_kses( (string) $v['name'], 'strip' ),
'source' => $v['source'],
'impact' => $v['impact'],
);
}
}
return ! empty( $core_data ) ? $core_data : false; // Return false if core_data is empty.
}
/**
* Get Vulnerabilities
*
* Retrieves and caches the vulnerabilities for the installed WordPress core version.
*
* @since 2.0.0
*
* @return string JSON-encoded array of core data with vulnerabilities and vulnerable status.
*/
function wpvulnerability_core_get_installed() {
$wpvulnerability_core_vulnerable = 0;
// Get fresh core vulnerabilities.
$core = wpvulnerability_get_fresh_core_vulnerabilities();
// Check if vulnerabilities were found and count them.
if ( is_array( $core ) && count( $core ) > 0 ) {
$wpvulnerability_core_vulnerable = count( $core );
}
// Cache the vulnerability data and the timestamp for cache expiration.
if ( is_multisite() ) {
update_site_option( 'wpvulnerability-core', wp_json_encode( $core ) );
update_site_option( 'wpvulnerability-core-vulnerable', wp_json_encode( number_format( $wpvulnerability_core_vulnerable, 0, '.', '' ) ) );
update_site_option( 'wpvulnerability-core-cache', wp_json_encode( number_format( time() + ( 3600 * wpvulnerability_cache_hours() ), 0, '.', '' ) ) );
} else {
update_option( 'wpvulnerability-core', wp_json_encode( $core ) );
update_option( 'wpvulnerability-core-vulnerable', wp_json_encode( number_format( $wpvulnerability_core_vulnerable, 0, '.', '' ) ) );
update_option( 'wpvulnerability-core-cache', wp_json_encode( number_format( time() + ( 3600 * wpvulnerability_cache_hours() ), 0, '.', '' ) ) );
}
// Return the JSON-encoded array of core vulnerabilities.
return wp_json_encode( $core );
}
/**
* Get the cached vulnerabilities or update the cache if it's stale or missing.
*
* @since 2.0.0
*
* @return array Array of core with their vulnerabilities.
*/
function wpvulnerability_core_get_vulnerabilities() {
// Initialize variables.
$core_data_cache = null;
$core_data = null;
if ( is_multisite() ) {
// Get the cached core data and decode it for multisite.
$core_data_cache = json_decode( get_site_option( 'wpvulnerability-core-cache' ), true );
$core_data = json_decode( get_site_option( 'wpvulnerability-core' ), true );
} else {
// Get the cached core data and decode it for single site.
$core_data_cache = json_decode( get_option( 'wpvulnerability-core-cache' ), true );
$core_data = json_decode( get_option( 'wpvulnerability-core' ), true );
}
// If the cache is stale or the core data is empty, update the cache.
if ( ( null !== $core_data_cache && $core_data_cache < time() ) || empty( $core_data ) ) {
$core_data = json_decode( wpvulnerability_core_get_installed(), true );
}
// Return the core data with vulnerabilities.
return $core_data;
}
/**
* Update the core cache and remove any old cache data.
*
* @since 2.0.0
*
* @return void
*/
function wpvulnerability_core_get_vulnerabilities_clean() {
wpvulnerability_clear_cache( 'core' );
wpvulnerability_core_get_installed();
}
/**
* Adds vulnerability information after the core version and notices on the update-core.php page.
*
* @since 2.0.0
*
* @return void
*/
function wpvulnerability_core_page() {
// Check if the current page is the update-core.php page.
global $pagenow;
if ( wpvulnerability_analyze_filter( 'core' ) && 'update-core.php' === $pagenow && wpvulnerability_capabilities() ) {
// Get the vulnerabilities for the core.
$core = wpvulnerability_core_get_vulnerabilities();
// If there are vulnerabilities, add an action to display them after the core auto updates settings.
if ( is_array( $core ) && ! empty( $core ) ) {
add_action( 'after_core_auto_updates_settings', 'wpvulnerability_core_info_after' );
}
}
}
// Add notices for vulnerable core on the core page.
add_action( 'admin_head', 'wpvulnerability_core_page' );