response_results = array();
}
public function run_issues_check()
{
$this->check_wordpress_update();
$this->get_outdated_plugins();
$this->check_php_version();
$this->check_db_password(DB_PASSWORD);
$this->firewall_check();
$this->check_permissions();
update_option('whp_scan_results', $this->response_results);
update_option('whp_scan_results_time', current_time('timestamp'));
}
public function wp_check_php_version() {
$version = phpversion();
$key = md5( $version );
$response = get_site_transient( 'php_check_' . $key );
if ( false === $response ) {
$url = 'http://api.wordpress.org/core/serve-happy/1.0/';
if ( wp_http_supports( array( 'ssl' ) ) ) {
$url = set_url_scheme( $url, 'https' );
}
$url = add_query_arg( 'php_version', $version, $url );
$response = wp_remote_get( $url );
if ( is_wp_error( $response ) || 200 !== wp_remote_retrieve_response_code( $response ) ) {
return false;
}
$response = json_decode( wp_remote_retrieve_body( $response ), true );
if ( ! is_array( $response ) ) {
return false;
}
set_site_transient( 'php_check_' . $key, $response, WEEK_IN_SECONDS );
}
if ( isset( $response['is_acceptable'] ) && $response['is_acceptable'] ) {
$response['is_acceptable'] = (bool) apply_filters( 'wp_is_php_version_acceptable', true, $version );
}
return $response;
}
public function check_php_version()
{
$version = explode('.', PHP_VERSION);
$msg = '';
$status = 'bad';
// Sets up PHP versions and dates.
$php_versions = array(
'5.0' => array(
'release' => 'July 13, 2004',
'eol' => 'September 5, 2005',
),
'5.1' => array(
'release' => 'November 24, 2005',
'eol' => 'August 24, 2006',
),
'5.2' => array(
'release' => 'November 2, 2006',
'eol' => 'January 6, 2011',
),
'5.3' => array(
'release' => 'June 30, 2009',
'eol' => 'August 14, 2014',
),
'5.4' => array(
'release' => 'March 1, 2012',
'eol' => 'September 3, 2015',
),
'5.5' => array(
'release' => 'June 20, 2013',
'eol' => 'July 21, 2016',
),
'5.6' => array(
'release' => 'August 28, 2014',
'eol' => 'December 31, 2018',
),
'7.0' => array(
'release' => 'December 3, 2015',
'eol' => 'December 2, 2018',
),
'7.1' => array(
'release' => 'December 1, 2016',
'eol' => 'December 1, 2019',
),
'7.2' => array(
'release' => 'November 30, 2017',
'eol' => 'November 30, 2020',
),
'7.3' => array(
'release' => 'December 6, 2018',
'eol' => 'December 6, 2021',
),
'7.4' => array(
'release' => 'December 6, 2018',
'eol' => 'December 6, 2025',
),
'8.0' => array(
'release' => 'November 26, 2020',
'eol' => 'November 26, 2023'
),
'8.1' => array(
'release' => 'November 25, 2021',
'eol' => 'November 25, 2024'
),
);
$error = __('Error checking PHP health.', 'whp');
if (!is_array($version) || count($version) < 2) {
return $this->prepare_array($error, $status, 'php_version', PHP_VERSION);
}
$site_version = $version[0] . '.' . $version[1];
$unsupported_version_message = sprintf(__('Your server is running PHP version %1$s which has not been supported since %2$s.', 'whp'), $site_version, $php_versions[$site_version]['eol']);
/* translators: %s: Version of PHP and the date the version of PHP stops receiving security updates */
$supported_version_message = sprintf(__('Good job! Your server is running PHP version %1$s which will receive security updates until %2$s.', 'whp'), $site_version, $php_versions[$site_version]['eol']);
$unsupported_message = __('Using an unsupported version of PHP means that you are using a version that no longer receives important security updates and fixes. Also, newer versions are faster which makes your site load faster. You must update your PHP or contact your host immediately!', 'whp');
$security_ending_message = __('Be sure to check with your host to make sure they have a plan to update before the security support ends.', 'whp');
$eol_time = strtotime($php_versions[$site_version]['eol']);
$today = time();
$data = $this->wp_check_php_version();
$string = $data['recommended_version'];
$system = phpversion();
$ststemversionExp = explode('.', $system);
array_pop($ststemversionExp);
$system= implode('.', $ststemversionExp);
if ($system != $string) {
// If EOL is passed, show unsupported message.
$msg = $unsupported_version_message . ' ' . $unsupported_message;
$this->response_results['php_version'] = array(
'status' => 'error',
'message' => sprintf(__('Your current PHP version (%s) is outdated and can invite hackers.', 'whp'), $system),
'details' => sprintf(__('Move to the latest and secured version (%s) with this guide here.', 'whp'), $data['recommended_version']),
);
} elseif ($system == $string) {
// If EOL is coming up within the next 180 days, show expiring soon message.
$msg = $supported_version_message . ' ' . $security_ending_message;
$this->response_results['php_version'] = array(
'status' => 'success',
'message' => __('Hurray! Your PHP version is up to date!', 'whp'),
'details' => sprintf(__('PHP version %s is recognized as the most secured version as of now. ', 'whp'), $site_version),
);
} else {
// If EOL is farther than 180 days out, show good message.
$this->response_results['php_version'] = array(
'status' => 'success',
'message' => __('Hurray! Your PHP version is up to date!', 'whp'),
'details' => sprintf(__('PHP version %s is recognized as the most secured version as of now. ', 'whp'), $site_version),
);
}
}
public function get_outdated_plugins()
{
require_once ABSPATH . 'wp-admin/includes/plugin.php';
$plugins_list = get_plugins();
$plugin_info = get_site_transient('update_plugins');
$plugins = array();
if (isset($plugin_info->response)) {
foreach ($plugin_info->response as $plugin) {
$plugin->title = $plugins_list[$plugin->plugin]['Name'];
$plugin->upgrade = true;
$plugins[$plugin->slug] = $plugin;
}
}
if (count($plugins) === 0) {
$this->response_results['inactive_plugins'] = array(
'status' => 'success',
'message' => 'Great! All your plugins are running on the latest versions.',
'details' => 'All plugins are running the latest versions.'
);
} else {
$list_of_plugins = array();
foreach ($plugins as $k => $v) {
$names[] = $v->title;
}
$this->response_results['inactive_plugins'] = array(
'status' => 'error',
'message' => __('Outdated plugins were detected on your website. Update them to the latest version to stay secure!', 'whp'),
'details' => sprintf(__('Plugins (%s) require immediate update. Follow this link to update now.', 'whp'), implode(', ', $names), admin_url('/plugins.php?plugin_status=upgrade'))
);
}
}
public function check_wordpress_update()
{
$local_version = get_bloginfo('version');
$url = 'https://api.wordpress.org/core/version-check/1.7/';
$response = wp_remote_get($url);
if (is_wp_error($response)) {
return false;
}
$json = $response['body'];
$obj = json_decode($json);
$upgrade = $obj->offers[0];
$current_version = $upgrade->version;
$res = version_compare($local_version, $current_version);
//local < current
if ($res === -1) {
$this->response_results['wp_version'] = array(
'status' => 'error',
'message' => __('You need to update WordPress to latest version', 'whp'),
'details' => sprintf(__('An older WordPress version was detected on your Website. Update it ASAP to keep yourself secure. You need to update WordPress to %s. Your current version is: %s', 'whp'), $current_version, $local_version),
);
} else {
$this->response_results['wp_version'] = array(
'status' => 'success',
'message' => __('Bravo! Your WordPress Version is up to date.', 'whp'),
'details' => sprintf(__('Your website is running the most secure version ( %s ) of WordPress.', 'whp'), $current_version),
);
}
}
public function check_db_password($pwd)
{
$errors = array();
if (strlen($pwd) < 8) {
$errors[] = __("Password too short!", 'whp');
}
if (!preg_match("#[0-9]+#", $pwd)) {
$errors[] = __("Password must include at least one number!", 'whp');
}
if (!preg_match("#[a-zA-Z]+#", $pwd)) {
$errors[] = __("Password must include at least one letter!", 'whp');
}
if (count($errors) == 0) {
$this->response_results['db_strength'] = array(
'status' => 'success',
'message' => __('Good job using strong passwords for your database.', 'whp'),
'details' => __('You are following good password practices for your website. We recommend that you change your passwords often.', 'whp'),
);
} else {
$this->response_results['db_strength'] = array(
'status' => 'error',
'message' => __('Sorry! The current database password is not strong. Try something more secure?', 'whp'),
'details' => __('Change to a stronger Password. Take help from this guide to create strong passwords for your website.', 'whp'),
);
}
}
public static function is_firewall_installed()
{
$firewalls_slugs = array(
'getastra/astra-security.php',
'astra_wp/astra_wp.php',
'astra_tc/astra_tc.php',
'wordfence/wordfence.php',
'wp-cerber/wp-cerber.php',
'better-wp-security/better-wp-security.php',
);
$active_plugins = get_option('active_plugins');
$has_firewall = 0;
foreach ($active_plugins as $s_plugin) {
if (in_array($s_plugin, $firewalls_slugs)) {
if ($s_plugin == 'getastra/astra-security.php') {
self::$is_astra = 1;
}
return true;
}
}
return false;
}
public function firewall_check()
{
if (!$this->is_firewall_installed()) {
$this->response_results['has_firewall'] = array(
'status' => 'error',
'message' => __('Oops! We were not able to detect any WordPress security plugin on your website. ', 'whp'),
'details' => __('Astra Firewall leverages continuous and comprehensive protection to your website. Astra firewall stops attacks like XSS, SQLi, LFI, RFI, Bad bots & 100+ type of security threats in real time.', 'whp'),
);
return false;
} else {
if (self::$is_astra == 1) {
$this->response_results['has_firewall'] = array(
'status' => 'success',
'message' => __('Oh wow! You are well-protected by Astra!', 'whp'),
'details' => __('Firewalls are a great way to monitor & protect your website against hacks. But, of course you know that :-) ', 'whp'),
);
} else {
$this->response_results['has_firewall'] = array(
'status' => 'success',
'message' => __('Nice! You have a firewall installed.', 'whp'),
'details' => __('Firewalls are a great way to monitor & protect your website against hacks. But, of course you know that :-) ', 'whp'),
);
}
return true;
}
}
public function check_permissions()
{
global $level;
$level = 0;
$result = $this->getDirContents(ABSPATH);
if (count($result) == 0) {
$this->response_results['file_permission'] = array(
'status' => 'success',
'message' => __('Correct file permissions are in place.', 'whp'),
'details' => __('File permissions ensure privacy as well as security of your website. Glad you know that too :-)', 'whp'),
);
} else {
$out_lines = array();
foreach ($result as $s_row) {
$out_lines[] = "
" . $s_row['permissions'] . '
' . $s_row['path'] . '
';
}
$this->response_results['file_permission'] = array(
'status' => 'error',
'message' => __('Poor file & folder permissions detected.', 'whp'),
'details' => __('Managing and securing file permission should not be overlooked. This guide will help you secure the recommended file permissions on your WordPress.
' .
__('This option allows you to set a network-wide default, which can be overridden by individual sites. Simply go to to the site’s permalink settings to change the url.', 'whp') .
'
' .
'
' .
'
' .
'
' .
__('Networkwide default', 'whp') .
'
' .
'
' .
'' .
'
' .
'
' .
'
'
);
}
public function update_wpmu_options()
{
if (
($whp_admin_page = sanitize_title_with_dashes($_POST['whp_admin_page'])) &&
strpos($whp_admin_page, 'wp-login') === false &&
!in_array($whp_admin_page, $this->forbidden_slugs())
) {
update_site_option('whp_admin_page', $whp_admin_page);
}
}
public function admin_init()
{
global $pagenow;
add_settings_section(
'rename-wp-login-section',
_x('Change Admin Login URL', 'Text string for settings page', 'whp'),
array($this, 'whp_section_desc'),
'permalink'
);
add_settings_field(
'whp-page',
'',
array($this, 'whp_admin_page_input'),
'permalink',
'change-wp-login-section'
);
if (isset($_POST['whp_admin_page']) && $pagenow === 'options-permalink.php') {
if (
($whp_admin_page = sanitize_title_with_dashes($_POST['whp_admin_page'])) &&
strpos($whp_admin_page, 'wp-login') === false &&
!in_array($whp_admin_page, $this->forbidden_slugs())
) {
if (is_multisite() && $whp_admin_page === get_site_option('whp_admin_page', 'login')) {
delete_option('whp_admin_page');
} else {
update_option('whp_admin_page', $whp_admin_page);
}
}
}
if (get_option('whp_redirect')) {
delete_option('whp_redirect');
if (is_multisite() && is_super_admin() && is_plugin_active_for_network($this->basename())) {
$redirect = network_admin_url('settings.php#whp-page-input');
} else {
$redirect = admin_url('options-permalink.php#whp-page-input');
}
wp_safe_redirect($redirect);
die;
}
}
public function whp_section_desc()
{
if (is_multisite() && is_super_admin() && is_plugin_active_for_network($this->basename())) {
echo(
'