| @@ -1771,16 +1771,8 @@ | ||
| 1771 | 1771 | $files = array( $hook_extra['plugin'] ); |
| 1772 | 1772 | } |
| 1773 | 1773 | foreach ( $files as $file ) { |
| 1774 | 1774 | $slug = dirname( (string) $file ); |
| 1775 | - // Vigilant itself is verified immediately (not after 90 s) by | |
| 1776 | - // Vigilante_Self_Integrity::handle_upgrader() when the | |
| 1777 | - // self-check is on; do not also open a grace window for it. | |
| 1778 | - // Compared with the folder it really lives in, not the literal | |
| 1779 | - // slug, so a renamed folder is skipped the same way. | |
| 1780 | - if ( dirname( VIGILANTE_PLUGIN_BASENAME ) === $slug && Vigilante_Self_Integrity::is_on() ) { | |
| 1781 | - continue; | |
| 1782 | - } | |
| 1783 | 1775 | if ( '.' !== $slug && '' !== $slug ) { |
| 1784 | 1776 | $targets['plugin'][] = $slug; |
| 1785 | 1777 | } |
| 1786 | 1778 | } |
| @@ -1849,17 +1841,8 @@ | ||
| 1849 | 1841 | */ |
| 1850 | 1842 | private function verify_updated_slug( $type, $slug ) { |
| 1851 | 1843 | $grace_key = 'vigilante_fi_grace_' . $type . '_' . md5( $slug ); |
| 1852 | 1844 | |
| 1853 | - // Defensive skip for the first 2.11.x -> 3.0.x update: the OLD code in | |
| 1854 | - // memory scheduled this event including Vigilant's own slug, and by the | |
| 1855 | - // time it fires the NEW code (this one) is running with the self-check | |
| 1856 | - // handling Vigilant on its own. | |
| 1857 | - if ( 'plugin' === $type && dirname( VIGILANTE_PLUGIN_BASENAME ) === $slug && Vigilante_Self_Integrity::is_on() ) { | |
| 1858 | - delete_transient( $grace_key ); | |
| 1859 | - return; | |
| 1860 | - } | |
| 1861 | - | |
| 1862 | 1845 | if ( 'plugin' === $type ) { |
| 1863 | 1846 | if ( ! function_exists( 'get_plugins' ) ) { |
| 1864 | 1847 | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
| 1865 | 1848 | } |
| @@ -2010,41 +1993,8 @@ | ||
| 2010 | 1993 | |
| 2011 | 1994 | // Use settings from options page |
| 2012 | 1995 | $options = is_array( $this->options ) ? $this->options : array(); |
| 2013 | 1996 | |
| 2014 | - // Vigilant self-check runs FIRST and exempt from the time budget: | |
| 2015 | - // ~60 small-file hashes cost < 50 ms and the guardian must never be | |
| 2016 | - // dropped by the budget on plugin-heavy sites. User exclusions do not | |
| 2017 | - // apply to it (see Vigilante_Self_Integrity::run_check()). | |
| 2018 | - if ( ! class_exists( 'Vigilante_Self_Integrity' ) ) { | |
| 2019 | - require_once VIGILANTE_INCLUDES_DIR . 'class-self-integrity.php'; | |
| 2020 | - } | |
| 2021 | - if ( Vigilante_Self_Integrity::is_on() ) { | |
| 2022 | - if ( ! class_exists( 'Vigilante_Self_Integrity' ) ) { | |
| 2023 | - require_once VIGILANTE_INCLUDES_DIR . 'class-self-integrity.php'; | |
| 2024 | - } | |
| 2025 | - $self = new Vigilante_Self_Integrity( $this->settings, $this->activity_log ); | |
| 2026 | - $self_result = $self->run_check( 'scan' ); | |
| 2027 | - // run_check() above updates this site's own state (status line and | |
| 2028 | - // the analyzer check keep working everywhere). The plugin files are | |
| 2029 | - // shared by the whole installation, so the self findings are folded | |
| 2030 | - // Self-protection has its own alert, and it does not travel in the | |
| 2031 | - // scan digest any more. That digest is governed by a notification | |
| 2032 | - // setting that can be switched off, and switching off "tell me about | |
| 2033 | - // changed files" was also switching off the alarm of the plugin | |
| 2034 | - // itself. So the findings stay out of the scan results (they have | |
| 2035 | - // their own block in File Integrity, with what each one means and how | |
| 2036 | - // to repair it) and a critical one sends its own email from here, | |
| 2037 | - // wherever the scan runs. maybe_send_self_alert() keeps it to the | |
| 2038 | - // site that owns the shared files and dedupes by set of findings. | |
| 2039 | - foreach ( (array) $self_result['findings'] as $self_finding ) { | |
| 2040 | - if ( 'critical' === ( $self_finding['severity'] ?? '' ) ) { | |
| 2041 | - $self->maybe_send_self_alert( $self_result['findings'], 'scan' ); | |
| 2042 | - break; | |
| 2043 | - } | |
| 2044 | - } | |
| 2045 | - } | |
| 2046 | - | |
| 2047 | 1997 | // Scan uploads for suspicious files FIRST (highest security priority) |
| 2048 | 1998 | // PHP files in uploads are almost always malware |
| 2049 | 1999 | if ( ! empty( $options['scan_uploads'] ) && ! $this->is_time_exceeded() ) { |
| 2050 | 2000 | $upload_results = $this->scan_uploads(); |
| @@ -3564,17 +3514,8 @@ | ||
| 3564 | 3514 | if ( '.' === $plugin_slug ) { |
| 3565 | 3515 | continue; |
| 3566 | 3516 | } |
| 3567 | 3517 | |
| 3568 | - // With the self-check on, Vigilant itself is verified by the | |
| 3569 | - // sha256 triple-anchor block at the start of run_scan(): scanning | |
| 3570 | - // it here again would duplicate findings and the md5 fetch. With | |
| 3571 | - // the check off by filter, Vigilant is a regular plugin (legacy | |
| 3572 | - // behaviour). | |
| 3573 | - if ( dirname( VIGILANTE_PLUGIN_BASENAME ) === $plugin_slug && Vigilante_Self_Integrity::is_on() ) { | |
| 3574 | - continue; | |
| 3575 | - } | |
| 3576 | - | |
| 3577 | 3518 | // Skip slugs in their post-update grace window: wp.org may still be |
| 3578 | 3519 | // publishing the new version's checksums, so a scheduled scan here |
| 3579 | 3520 | // would raise benign "modified/extra" noise. The dedicated post-update |
| 3580 | 3521 | // verifier (vigilante_fi_postupdate_verify) handles these instead. |
| @@ -4821,26 +4762,8 @@ | ||
| 4821 | 4762 | if ( is_multisite() && is_array( $item ) && 'critical_config' === ( $item['type'] ?? '' ) ) { |
| 4822 | 4763 | return true; |
| 4823 | 4764 | } |
| 4824 | 4765 | |
| 4825 | - // Findings about the manifest and the version of Vigilant | |
| 4826 | - // itself are not about one file, so no entry of the list may | |
| 4827 | - // hide them, on a single site either: ignoring the row of | |
| 4828 | - // MANIFEST.sha256 took a replaced manifest out of the email. | |
| 4829 | - // Vigilante_Self_Integrity::filter_ignored_findings() keeps | |
| 4830 | - // them the same way. | |
| 4831 | - if ( is_array( $item ) && 'vigilante_self' === ( $item['type'] ?? '' ) && in_array( $item['self_finding'] ?? '', array( 'manifest_replaced', 'manifest_unverified', 'manifest_missing', 'manifest_invalid', 'self_downgraded' ), true ) ) { | |
| 4832 | - return true; | |
| 4833 | - } | |
| 4834 | - // Nor the findings of the walk of Vigilant's folder (a folder | |
| 4835 | - // that cannot be listed, the folder that could not be walked): | |
| 4836 | - // their path ends in a slash, and ignoring that row left the | |
| 4837 | - // scan with no row and no email while the self-protection | |
| 4838 | - // status stayed critical. | |
| 4839 | - if ( is_array( $item ) && 'vigilante_self' === ( $item['type'] ?? '' ) && '/' === substr( (string) ( $item['file'] ?? '' ), -1 ) ) { | |
| 4840 | - return true; | |
| 4841 | - } | |
| 4842 | - | |
| 4843 | 4766 | $file = is_array( $item ) && isset( $item['file'] ) ? $item['file'] : ''; |
| 4844 | 4767 | return ! in_array( $file, $this->ignored_files, true ); |
| 4845 | 4768 | } |
| 4846 | 4769 | ) |
| @@ -4877,17 +4800,9 @@ | ||
| 4877 | 4800 | // a security-critical finding, same tier as a suspicious file. |
| 4878 | 4801 | $closed_plugins = $this->collect_closed_plugins_for_email(); |
| 4879 | 4802 | $has_closed = ! empty( $closed_plugins ); |
| 4880 | 4803 | |
| 4881 | - /* | |
| 4882 | - * Self-protection is not part of this decision any more. Its alert is | |
| 4883 | - * its own and no setting switches it off, so this email is again about | |
| 4884 | - * the files of the site: core, plugins, themes, uploads and the two | |
| 4885 | - * shared configuration files. | |
| 4886 | - */ | |
| 4887 | 4804 | $has_suspicious = ! empty( $results['suspicious'] ) || ! empty( $results['extra'] ) || $has_critical_config || $has_closed; |
| 4888 | - // Missing files of core, plugins or themes still do not send the email on | |
| 4889 | - // their own: it has no section to list them in, so it would arrive empty. | |
| 4890 | 4805 | $has_modified = ! empty( $results['modified'] ); |
| 4891 | 4806 | |
| 4892 | 4807 | // Instant alert: send for suspicious, extra, critical_config, modified |
| 4893 | 4808 | // files, or closed plugins. |
| @@ -5006,37 +4921,8 @@ | ||
| 5006 | 4921 | $regular_modified[] = $item; |
| 5007 | 4922 | } |
| 5008 | 4923 | } |
| 5009 | 4924 | |
| 5010 | - /* | |
| 5011 | - * Self-protection does not travel in this email any more: it has its own | |
| 5012 | - * alert, which no setting switches off (Vigilante_Self_Integrity:: | |
| 5013 | - * maybe_send_self_alert()). Older stored results can still carry its | |
| 5014 | - * rows, so they are dropped here instead of being listed as ordinary | |
| 5015 | - * files. | |
| 5016 | - */ | |
| 5017 | - foreach ( array( 'suspicious', 'extra', 'missing' ) as $self_bucket ) { | |
| 5018 | - if ( empty( $results[ $self_bucket ] ) || ! is_array( $results[ $self_bucket ] ) ) { | |
| 5019 | - continue; | |
| 5020 | - } | |
| 5021 | - $results[ $self_bucket ] = array_values( | |
| 5022 | - array_filter( | |
| 5023 | - $results[ $self_bucket ], | |
| 5024 | - function ( $item ) { | |
| 5025 | - return ! ( is_array( $item ) && 'vigilante_self' === ( $item['type'] ?? '' ) ); | |
| 5026 | - } | |
| 5027 | - ) | |
| 5028 | - ); | |
| 5029 | - } | |
| 5030 | - $regular_modified = array_values( | |
| 5031 | - array_filter( | |
| 5032 | - $regular_modified, | |
| 5033 | - function ( $item ) { | |
| 5034 | - return ! ( is_array( $item ) && 'vigilante_self' === ( $item['type'] ?? '' ) ); | |
| 5035 | - } | |
| 5036 | - ) | |
| 5037 | - ); | |
| 5038 | - | |
| 5039 | 4925 | $suspicious_count = count( $results['suspicious'] ?? array() ); |
| 5040 | 4926 | $extra_count = count( $results['extra'] ?? array() ); |
| 5041 | 4927 | $critical_config_count = count( $critical_config ); |
| 5042 | 4928 | $modified_count = count( $regular_modified ); |
| @@ -5041,10 +4927,10 @@ | ||
| 5041 | 4927 | $critical_config_count = count( $critical_config ); |
| 5042 | 4928 | $modified_count = count( $regular_modified ); |
| 5043 | 4929 | $closed_count = count( $closed_plugins ); |
| 5044 | 4930 | |
| 5045 | - // Use more urgent subject when suspicious files, critical config changes, | |
| 5046 | - // closed plugins or self-integrity findings are found (all security-critical). | |
| 4931 | + // Use more urgent subject when suspicious files, critical config changes | |
| 4932 | + // or closed plugins are found (all three are security-critical). | |
| 5047 | 4933 | if ( $suspicious_count > 0 || $critical_config_count > 0 || $closed_count > 0 ) { |
| 5048 | 4934 | $subject = sprintf( |
| 5049 | 4935 | /* translators: %s: Site name */ |
| 5050 | 4936 | __( '[%s] SECURITY ALERT: File integrity issues detected', 'vigilante' ), |