From c826b5b7c1e5bf029bdee7352ca9b479c5c65765 Mon Sep 17 00:00:00 2001
From: Michael <github@michaelplas.de>
Date: Sat, 9 Sep 2023 00:17:01 +0200
Subject: [PATCH] Refreshed Patch for #47528 - including check for development
 enviroment and releases

---
 src/wp-admin/admin-ajax.php                   |  1 +
 src/wp-admin/includes/ajax-actions.php        | 19 ++++
 .../includes/class-wp-site-health.php         | 96 ++++++++++++++++++-
 3 files changed, 115 insertions(+), 1 deletion(-)

diff --git a/src/wp-admin/admin-ajax.php b/src/wp-admin/admin-ajax.php
index fb19110029..64d0a002c9 100644
--- a/src/wp-admin/admin-ajax.php
+++ b/src/wp-admin/admin-ajax.php
@@ -139,6 +139,7 @@ $core_actions_post = array(
 	'health-check-background-updates',
 	'health-check-loopback-requests',
 	'health-check-get-sizes',
+	'health-check-core-integrity',
 	'toggle-auto-updates',
 	'send-password-reset',
 );
diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php
index 16b827d7bd..01bc4a3d8d 100644
--- a/src/wp-admin/includes/ajax-actions.php
+++ b/src/wp-admin/includes/ajax-actions.php
@@ -5486,6 +5486,25 @@ function wp_ajax_health_check_get_sizes() {
 	wp_send_json_success( $all_sizes );
 }
 
+/**
+ * Ajax handler for site health checks on code integrity.
+ *
+ * @since 6.4.0
+ */
+function wp_ajax_health_check_core_integrity() {
+	check_ajax_referer( 'health-check-site-status' );
+
+	if ( ! current_user_can( 'view_site_health_checks' ) ) {
+			wp_send_json_error();
+	}
+
+	if ( ! class_exists( 'WP_Site_Health' ) ) {
+			require_once( ABSPATH . 'wp-admin/includes/class-wp-site-health.php' );
+	}
+
+	$site_health = new WP_Site_Health();
+	wp_send_json_success( $site_health->get_test_core_integrity() );
+}
 /**
  * Handles renewing the REST API nonce via AJAX.
  *
diff --git a/src/wp-admin/includes/class-wp-site-health.php b/src/wp-admin/includes/class-wp-site-health.php
index 5ab784af40..5d157636b3 100644
--- a/src/wp-admin/includes/class-wp-site-health.php
+++ b/src/wp-admin/includes/class-wp-site-health.php
@@ -2697,6 +2697,89 @@ class WP_Site_Health {
 		return $result;
 	}
 
+	/**
+	 * Scan the WordPress core files for modified and/or missing files.
+	 *
+	 * Files that have been modified or that have gone missing may indicate that the site
+	 * has been compromised, installation failure, or that the code has been customized.
+	 * Users that know the code base should be unaltered will be offered to reinstall or
+	 * upgrade WordPress in response.
+	 *
+	 * @since 6.4.0
+	 *
+	 * @return array The test results.
+	 */
+	public function get_test_core_integrity() {
+		$result = array(
+			'label'       => __( 'No changes to the core files are detected' ),
+			'status'      => 'good',
+			'badge'       => array(
+				'label' => __( 'Security' ),
+				'color' => 'blue',
+			),
+			'description' => __( 'A scan for changes to the core WordPress files was performed. No changes are detected.' ),
+			'actions'     => '',
+			'test'        => 'core_integrity',
+                );
+
+		$wp_version = get_bloginfo( 'version' );
+		$wp_locale  = get_locale();
+
+		// Retrieve a list of checksums from the remote server for verification
+
+		$checksums = get_transient( 'health-check-code-integrity-checksums' );
+		if ( false === $checksums ) {
+			$checksums = get_core_checksums( $wp_version, $wp_locale );
+			if ( false === $checksums && false !== strpos( $wp_version, '-' ) ) {
+				$checksums = get_core_checksums( (float) $wp_version - 0.1, $wp_locale );
+                	}
+
+			set_transient( 'health-check-code-integrity-checksums', $checksums, HOUR_IN_SECONDS );
+		}
+
+		if ( empty( $checksums ) ) {
+			$result['status']      = 'critical';
+			$result['label']       = __( 'Unable to scan core files for changes' );
+			$result['description'] = __( 'The checksum file list could not be downloaded. There maybe a connection issue or a list is not available for this version. Please try to run this test again at a later time.' );
+			return $result;
+		}
+
+		$changed_files = false;
+		foreach ( $checksums as $file => $checksum ) {
+
+			if ( 0 === strncmp( $file, 'wp-content', 10 ) ) {
+				continue;
+			}
+
+			if ( ! file_exists( ABSPATH . $file ) ) {
+				$changed_files = true;
+				break;
+			}
+
+			$existing_checksum = md5_file( ABSPATH . $file );
+			if ( $existing_checksum !== $checksum ) {
+				$changed_files = true;
+				break;
+			}
+
+		}
+
+		if ( true === $changed_files ) {
+
+			$result['status'] = 'recommended';
+			$result['label']  = __( 'Some core files may have been modified' );
+			$result['description'] = __( 'Some WordPress core files may have been changed. One reason this check can fail is that you need to install a version that makes use of the right translation files. If you have the ability to do so, a simple fix is to reinstall WordPress. Reinstall of the core system should not affect any plugins, themes, or content that you have posted.' );
+			$result['actions'] = sprintf(
+				'<a href="%s">%s</a>',
+				esc_url( admin_url( 'update-core.php?force_check=1' ) ),
+				__( 'Reinstall WordPress manually' )
+			);
+
+		}
+
+		return $result;
+	}
+
 	/**
 	 * Returns a set of tests that belong to the site status page.
 	 *
@@ -2840,9 +2923,20 @@ class WP_Site_Health {
 			);
 		}
 
+		/*
+ 		 * Check integrity only for non-development environments and releases.
+ 		 * WordPress Nightly Builds, Alphas, and Betas contain a version suffix starting with "-", such as 6.4-alpha-56267-src.
+ 		 */
+		if ( !wp_is_development_mode(false) && !strpos(get_bloginfo('version'), '-') ) {
+			$tests['direct']['core_integrity']  = array(
+				'label' => __( 'WordPress Core Files Integrity Check' ),
+				'test'  => 'core_integrity'
+			);
+		}
+
 		/**
 		 * Filters which site status tests are run on a site.
-		 *
+		 * 
 		 * The site health is determined by a set of tests based on best practices from
 		 * both the WordPress Hosting Team and web standards in general.
 		 *
-- 
2.30.0.windows.2

