| 1732 | /** |
| 1733 | * Scan the WordPress codebase for modified and/or missing files. |
| 1734 | * |
| 1735 | * Files that have been modified or that have gone missing may indicate that the site |
| 1736 | * has been compromised, installation failure, or that the code has been customized. |
| 1737 | * Users that know the code base should be unaltered will be offered to reinstall or |
| 1738 | * upgrade WordPress in response. |
| 1739 | * |
| 1740 | * @since 5.3.0 |
| 1741 | * |
| 1742 | * @return array The test results. |
| 1743 | */ |
| 1744 | public function get_test_code_integrity() { |
| 1745 | $result = array( |
| 1746 | 'label' => __( 'No changes to the core files are detected' ), |
| 1747 | 'status' => 'good', |
| 1748 | 'badge' => array( |
| 1749 | 'label' => __( 'Security' ), |
| 1750 | 'color' => 'blue', |
| 1751 | ), |
| 1752 | 'description' => __( 'A scan for changes to the core WordPress files was performed. No changes are detected.' ), |
| 1753 | 'actions' => '', |
| 1754 | 'test' => 'code_integrity', |
| 1755 | ); |
| 1756 | |
| 1757 | $wp_version = get_bloginfo( 'version' ); |
| 1758 | $wp_locale = get_locale(); |
| 1759 | |
| 1760 | // Retrieve a list of checksums from the remote server for verification |
| 1761 | |
| 1762 | $checksums = get_transient( 'health-check-code-integrity-checksums' ); |
| 1763 | if ( false === $checksums ) { |
| 1764 | $checksums = get_core_checksums( $wp_version, $wp_locale ); |
| 1765 | if ( false === $checksums && false !== strpos( $wp_version, '-' ) ) { |
| 1766 | $checksums = get_core_checksums( (float) $wp_version - 0.1, $wp_locale ); |
| 1767 | } |
| 1768 | |
| 1769 | set_transient( 'health-check-code-integrity-checksums', $checksums, HOURS_IN_SECONDS ); |
| 1770 | } |
| 1771 | |
| 1772 | if ( empty( $checksums ) ) { |
| 1773 | $result['status'] = 'critical'; |
| 1774 | $result['label'] = 'Unable to scan core files for changes'; |
| 1775 | $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.' ); |
| 1776 | return $result; |
| 1777 | } |
| 1778 | |
| 1779 | $changed_files = false; |
| 1780 | foreach ( $checksums as $file => $checksum ) { |
| 1781 | |
| 1782 | if ( 0 === strncmp( $file, 'wp-content', 10 ) ) { |
| 1783 | continue; |
| 1784 | } |
| 1785 | |
| 1786 | if ( ! file_exists( ABSPATH . $file ) ) { |
| 1787 | $changed_files = true; |
| 1788 | break; |
| 1789 | } |
| 1790 | |
| 1791 | $existing_checksum = md5_file( ABSPATH . $file ); |
| 1792 | if ( $existing_checksum !== $checksum ) { |
| 1793 | $changed_files = true; |
| 1794 | break; |
| 1795 | } |
| 1796 | |
| 1797 | } |
| 1798 | |
| 1799 | if ( true === $changed_files ) { |
| 1800 | |
| 1801 | $result['status'] = 'recommended'; |
| 1802 | $result['label'] = __( 'Some core files may have been modified' ); |
| 1803 | $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.' ); |
| 1804 | $result['actions'] = sprintf( |
| 1805 | '<a href="%s">%s</a>', |
| 1806 | esc_url( admin_url( 'update-core.php?force_check=1' ) ), |
| 1807 | __( 'Reinstall WordPress manually' ) |
| 1808 | ); |
| 1809 | |
| 1810 | } |
| 1811 | |
| 1812 | return $result; |
| 1813 | } |
| 1814 | |