File: /home/emerlux/public_html/wp-content/plugins/wpvulnerability/wpvulnerability-api.php
<?php
/**
* WPVulnerability REST API Endpoints
*
* @package WPVulnerability
*
* @since 3.3.0
*/
/**
* Handle the core vulnerabilities REST API request.
*
* This function handles the request for retrieving core vulnerabilities.
* It includes the necessary files and fetches the vulnerabilities data.
*
* @since 3.3.0
*
* @return WP_REST_Response Core vulnerabilities data or a message if none found.
*/
function wpvulnerability_rest_core_vulnerabilities() {
// Include the files containing the functions to get core vulnerabilities.
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-general.php';
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-core.php';
// Get the core vulnerabilities.
$core_vulnerabilities = wpvulnerability_core_get_vulnerabilities();
$core_complete = array();
$vulnerabilities = array();
// Check if vulnerabilities are found and is an array.
if ( $core_vulnerabilities && is_array( $core_vulnerabilities ) ) {
// Loop through each core vulnerability.
foreach ( $core_vulnerabilities as $vulnerability ) {
$core_complete_temp = array();
// Process vulnerability version.
$core_complete_temp['version'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['name'], 'strip' ) ) );
// Process vulnerability severity.
$core_complete_temp['severity'] = null;
if ( isset( $vulnerability['impact']['cvss']['severity'] ) ) {
$core_complete_temp['severity'] = wpvulnerability_severity( $vulnerability['impact']['cvss']['severity'] );
}
// Process CWE details.
$core_complete_temp['cwe'] = array();
if ( isset( $vulnerability['impact']['cwe'] ) && count( $vulnerability['impact']['cwe'] ) ) {
foreach ( $vulnerability['impact']['cwe'] as $vulnerability_cwe ) {
$core_complete_temp['cwe'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $vulnerability_cwe['name'], 'strip' ) ) ),
'description' => trim( html_entity_decode( wp_kses( (string) $vulnerability_cwe['description'], 'strip' ) ) ),
);
}
}
// Process CVSS score.
$core_complete_temp['score'] = null;
if ( isset( $vulnerability['impact']['cvss']['score'] ) ) {
$core_complete_temp['score'] = number_format( (float) $vulnerability['impact']['cvss']['score'], 1, '.', '' );
}
// Process vulnerability sources.
$core_complete_temp['source'] = array();
if ( isset( $vulnerability['source'] ) && count( $vulnerability['source'] ) ) {
foreach ( $vulnerability['source'] as $vulnerability_source ) {
$core_complete_temp['source'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $vulnerability_source['name'], 'strip' ) ) ),
'link' => esc_url_raw( (string) $vulnerability_source['link'], 'strip' ),
'description' => trim( html_entity_decode( wp_kses( (string) $vulnerability_source['description'], 'strip' ) ) ),
);
}
}
$core_complete[] = $core_complete_temp;
unset( $core_complete_temp );
}
}
// Return the vulnerabilities in the response.
return new WP_REST_Response( $core_complete, 200 );
}
/**
* Handle the plugins vulnerabilities REST API request.
*
* This function handles the request for retrieving plugins vulnerabilities.
* It includes the necessary files and fetches the vulnerabilities data.
*
* @since 3.3.0
*
* @return WP_REST_Response Plugins vulnerabilities data or a message if none found.
*/
function wpvulnerability_rest_plugins_vulnerabilities() {
// Include the files containing the functions to get plugins vulnerabilities.
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-general.php';
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-plugins.php';
// Get the plugins vulnerabilities.
$plugins_vulnerabilities = wpvulnerability_plugin_get_vulnerabilities();
$plugins_complete = array();
// Loop through each plugin vulnerability.
foreach ( $plugins_vulnerabilities as $plugin ) {
// Check if the plugin is vulnerable.
if ( 1 === $plugin['vulnerable'] ) {
$plugins_complete_temp = array();
// Process plugin name and slug.
$plugins_complete_temp['name'] = trim( html_entity_decode( wp_kses( (string) $plugin['Name'], 'strip' ) ) );
$plugins_complete_temp['slug'] = trim( html_entity_decode( wp_kses( (string) $plugin['slug'], 'strip' ) ) );
// Prepare the vulnerabilities array for output.
foreach ( $plugin['vulnerabilities'] as $vulnerability ) {
$plugins_complete_temp_vulnerabilities = array();
// Process vulnerability severity.
$plugins_complete_temp_vulnerabilities['severity'] = null;
if ( isset( $vulnerability['impact']['cvss']['severity'] ) ) {
$plugins_complete_temp_vulnerabilities['severity'] = wpvulnerability_severity( $vulnerability['impact']['cvss']['severity'] );
}
// Process vulnerability details.
$plugins_complete_temp_vulnerabilities['version'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['version'], 'strip' ) ) );
$plugins_complete_temp_vulnerabilities['affected'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['versions'], 'strip' ) ) );
$plugins_complete_temp_vulnerabilities['name'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['name'], 'strip' ) ) );
$plugins_complete_temp_vulnerabilities['closed'] = (int) $vulnerability['closed'];
$plugins_complete_temp_vulnerabilities['unfixed'] = (int) $vulnerability['unfixed'];
// Process CWE details.
$plugins_complete_temp_vulnerabilities['cwe'] = array();
if ( isset( $vulnerability['impact']['cwe'] ) && count( $vulnerability['impact']['cwe'] ) ) {
foreach ( $vulnerability['impact']['cwe'] as $vulnerability_cwe ) {
$plugins_complete_temp_vulnerabilities['cwe'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $vulnerability_cwe['name'], 'strip' ) ) ),
'description' => trim( html_entity_decode( wp_kses( (string) $vulnerability_cwe['description'], 'strip' ) ) ),
);
}
}
// Process CVSS score.
$plugins_complete_temp_vulnerabilities['score'] = null;
if ( isset( $vulnerability['impact']['cvss']['score'] ) ) {
$plugins_complete_temp_vulnerabilities['score'] = number_format( (float) $vulnerability['impact']['cvss']['score'], 1, '.', '' );
}
// Process vulnerability sources.
$plugins_complete_temp_vulnerabilities['source'] = array();
if ( isset( $vulnerability['source'] ) && count( $vulnerability['source'] ) ) {
foreach ( $vulnerability['source'] as $vulnerability_source ) {
$plugins_complete_temp_vulnerabilities['source'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $vulnerability_source['name'], 'strip' ) ) ),
'link' => esc_url_raw( (string) $vulnerability_source['link'], 'strip' ),
);
}
}
// Add processed vulnerability to the temporary array.
$plugins_complete_temp['vulnerabilities'][] = $plugins_complete_temp_vulnerabilities;
}
// Add processed plugin data to the complete array.
$plugins_complete[] = $plugins_complete_temp;
}
}
// Return the vulnerabilities in the response.
return new WP_REST_Response( $plugins_complete, 200 );
}
/**
* Handle the themes vulnerabilities REST API request.
*
* This function handles the request for retrieving themes vulnerabilities.
* It includes the necessary files and fetches the vulnerabilities data.
*
* @since 3.3.0
*
* @return WP_REST_Response Themes vulnerabilities data or a message if none found.
*/
function wpvulnerability_rest_themes_vulnerabilities() {
// Include the file containing the function to get themes vulnerabilities.
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-general.php';
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-themes.php';
// Get the themes vulnerabilities.
$themes_vulnerabilities = wpvulnerability_theme_get_vulnerabilities();
$themes_complete = array();
// Loop through each theme vulnerability.
foreach ( $themes_vulnerabilities as $theme ) {
// Check if the theme is vulnerable.
if ( 1 === $theme['wpvulnerability']['vulnerable'] ) {
$themes_complete_temp = array();
// Process theme name and slug.
$themes_complete_temp['name'] = trim( html_entity_decode( wp_kses( (string) $theme['wpvulnerability']['name'], 'strip' ) ) );
$themes_complete_temp['slug'] = trim( html_entity_decode( wp_kses( (string) $theme['wpvulnerability']['slug'], 'strip' ) ) );
// Prepare the vulnerabilities array for output.
foreach ( $theme['wpvulnerability']['vulnerabilities'] as $vulnerability ) {
$themes_complete_temp_vulnerabilities = array();
// Process vulnerability severity.
$themes_complete_temp_vulnerabilities['severity'] = null;
if ( isset( $vulnerability['impact']['cvss']['severity'] ) ) {
$themes_complete_temp_vulnerabilities['severity'] = wpvulnerability_severity( $vulnerability['impact']['cvss']['severity'] );
}
// Process vulnerability details.
$themes_complete_temp_vulnerabilities['version'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['version'], 'strip' ) ) );
$themes_complete_temp_vulnerabilities['affected'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['versions'], 'strip' ) ) );
$themes_complete_temp_vulnerabilities['name'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['name'], 'strip' ) ) );
$themes_complete_temp_vulnerabilities['closed'] = (int) $vulnerability['closed'];
$themes_complete_temp_vulnerabilities['unfixed'] = (int) $vulnerability['unfixed'];
// Process CWE details.
$themes_complete_temp_vulnerabilities['cwe'] = array();
if ( isset( $vulnerability['impact']['cwe'] ) && count( $vulnerability['impact']['cwe'] ) ) {
foreach ( $vulnerability['impact']['cwe'] as $vulnerability_cwe ) {
$themes_complete_temp_vulnerabilities['cwe'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $vulnerability_cwe['name'], 'strip' ) ) ),
'description' => trim( html_entity_decode( wp_kses( (string) $vulnerability_cwe['description'], 'strip' ) ) ),
);
}
}
// Process CVSS score.
$themes_complete_temp_vulnerabilities['score'] = null;
if ( isset( $vulnerability['impact']['cvss']['score'] ) ) {
$themes_complete_temp_vulnerabilities['score'] = number_format( (float) $vulnerability['impact']['cvss']['score'], 1, '.', '' );
}
// Process vulnerability sources.
$themes_complete_temp_vulnerabilities['source'] = array();
if ( isset( $vulnerability['source'] ) && count( $vulnerability['source'] ) ) {
foreach ( $vulnerability['source'] as $vulnerability_source ) {
$themes_complete_temp_vulnerabilities['source'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $vulnerability_source['name'], 'strip' ) ) ),
'link' => esc_url_raw( (string) $vulnerability_source['link'], 'strip' ),
);
}
}
// Add processed vulnerability to the temporary array.
$themes_complete_temp['vulnerabilities'][] = $themes_complete_temp_vulnerabilities;
}
// Add processed theme data to the complete array.
$themes_complete[] = $themes_complete_temp;
}
}
// Return the vulnerabilities in the response.
return new WP_REST_Response( $themes_complete, 200 );
}
/**
* Handle vulnerabilities REST API request for different software types.
*
* This function processes the request to retrieve vulnerabilities for the specified software type.
* It loads the necessary files and fetches the vulnerability data, then returns the data in a structured format.
*
* @since 3.5.0
*
* @param string $software_type The type of software to retrieve vulnerabilities for.
* @return WP_REST_Response The vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_software_vulnerabilities( $software_type ) {
// Include the general file for retrieving vulnerabilities.
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-general.php';
require_once WPVULNERABILITY_PLUGIN_PATH . '/wpvulnerability-software.php';
// Get vulnerabilities based on the software type.
$vulnerabilities = array();
switch ( $software_type ) {
case 'php':
case 'apache':
case 'nginx':
case 'mariadb':
case 'mysql':
case 'imagemagick':
case 'curl':
case 'memcached':
case 'redis':
case 'sqlite':
$vulnerabilities = wpvulnerability_get_vulnerabilities( $software_type, wpvulnerability_get_software_version( $software_type ) );
break;
default:
WP_REST_Response( array(), 400 ); // Invalid software type.
}
$complete_vulnerabilities = array();
if ( isset( $vulnerabilities ) && is_array( $vulnerabilities ) ) {
// Process each vulnerability.
foreach ( $vulnerabilities as $vulnerability ) {
$temp = array();
$temp['version'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['version'], 'strip' ) ) );
$temp['affected'] = trim( html_entity_decode( wp_kses( (string) $vulnerability['versions'], 'strip' ) ) );
$temp['unfixed'] = (int) $vulnerability['unfixed'];
// Process vulnerability sources.
$temp['source'] = array();
if ( isset( $vulnerability['source'] ) && count( $vulnerability['source'] ) ) {
foreach ( $vulnerability['source'] as $source ) {
$temp['source'][] = array(
'name' => trim( html_entity_decode( wp_kses( (string) $source['id'], 'strip' ) ) ),
'description' => trim( html_entity_decode( wp_kses( (string) $source['description'], 'strip' ) ) ),
'link' => esc_url_raw( (string) $source['link'], 'strip' ),
);
}
}
// Add processed vulnerability to the complete array.
$complete_vulnerabilities[] = $temp;
}
}
// Return the vulnerabilities in the response.
return new WP_REST_Response( $complete_vulnerabilities, 200 );
}
/**
* Handle the PHP vulnerabilities REST API request.
*
* @since 3.3.0
*
* @return WP_REST_Response PHP vulnerabilities data or a message if none found.
*/
function wpvulnerability_rest_php_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'php' );
}
/**
* Handle the Apache vulnerabilities REST API request.
*
* @since 3.3.0
*
* @return WP_REST_Response Apache vulnerabilities data or a message if none found.
*/
function wpvulnerability_rest_apache_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'apache' );
}
/**
* Handle the Nginx vulnerabilities REST API request.
*
* @since 3.3.0
*
* @return WP_REST_Response Nginx vulnerabilities data or a message if none found.
*/
function wpvulnerability_rest_nginx_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'nginx' );
}
/**
* Handle the MariaDB vulnerabilities REST API request.
*
* @since 3.4.0
*
* @return WP_REST_Response MariaDB vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_mariadb_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'mariadb' );
}
/**
* Handle the MySQL vulnerabilities REST API request.
*
* @since 3.4.0
*
* @return WP_REST_Response MySQL vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_mysql_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'mysql' );
}
/**
* Handle the ImageMagick vulnerabilities REST API request.
*
* @since 3.5.0
*
* @return WP_REST_Response ImageMagick vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_imagemagick_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'imagemagick' );
}
/**
* Handle the curl vulnerabilities REST API request.
*
* @since 3.5.0
*
* @return WP_REST_Response curl vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_curl_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'curl' );
}
/**
* Handle the memcached vulnerabilities REST API request.
*
* @since 3.5.0
*
* @return WP_REST_Response memcached vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_memcached_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'memcached' );
}
/**
* Handle the Redis vulnerabilities REST API request.
*
* @since 3.5.0
*
* @return WP_REST_Response Redis vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_redis_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'redis' );
}
/**
* Handle the SQLite vulnerabilities REST API request.
*
* @since 3.5.0
*
* @return WP_REST_Response SQLite vulnerabilities data or an empty array if none found.
*/
function wpvulnerability_rest_sqlite_vulnerabilities() {
return wpvulnerability_rest_software_vulnerabilities( 'sqlite' );
}
/**
* Custom permission check for the WPVulnerability REST API.
*
* This function checks if the request is authenticated using an Application Password.
*
* @since 3.3.0
*
* @param WP_REST_Request $request The REST API request.
*
* @return bool True if the user has permission, false otherwise.
*/
function wpvulnerability_permission_check( WP_REST_Request $request ) {
// Check if application passwords are available.
if ( function_exists( 'wp_is_application_passwords_available' ) && wp_is_application_passwords_available() ) {
$authorization_header = $request->get_header( 'authorization' );
// Check if the authorization header is present and properly formatted.
if ( $authorization_header && preg_match( '/^Basic\s(.+)$/i', $authorization_header, $matches ) ) {
$auth_string = base64_decode( (string) $matches[1] ); // phpcs:ignore
list( $user, $password ) = explode( ':', $auth_string );
// Authenticate the user using the application password.
if ( wp_authenticate_application_password( null, $user, $password ) instanceof WP_User ) {
return true;
}
}
}
return false;
}
/**
* Registers REST API routes for WPVulnerability.
*
* This function sets up the REST API routes for WPVulnerability to handle requests
* related to vulnerabilities in various components like core, plugins, themes, PHP, and more.
*
* @since 3.3.0
*
* @return void
*/
function wpvulnerability_register_rest_routes() {
// Define the endpoints to be registered.
$endpoints = array(
'core',
'plugins',
'themes',
'php',
'apache',
'nginx',
'mariadb',
'mysql',
'imagemagick',
'curl',
'memcached',
'redis',
'sqlite',
);
// Loop through each endpoint and register it.
foreach ( $endpoints as $endpoint ) {
register_rest_route(
'wpvulnerability/v1', // Namespace and version.
'/' . $endpoint, // Endpoint URL.
array(
'methods' => 'GET', // HTTP method.
'callback' => 'wpvulnerability_rest_' . $endpoint . '_vulnerabilities', // Callback function.
'permission_callback' => 'wpvulnerability_permission_check', // Permission check callback.
)
);
}
}
// Hook to initialize REST API endpoints.
add_action( 'rest_api_init', 'wpvulnerability_register_rest_routes' );