PluginProbe
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… / 2.11.12
Vigilant – 100% Free Security Suite: Firewall, 2FA, Login, Headers, Scanner… v2.11.12
3.0.0 2.11.12 2.11.11 2.11.10 2.11.9 2.11.7 2.11.8 2.11.6 2.11.5 2.11.4 2.11.3 2.11.1 2.11.2 2.11.0 2.10.5 2.10.4 2.10.3 2.10.2 2.10.1 2.10.0 2.9.9 2.9.8 2.9.6 2.9.7 2.9.5 All 88 releases
← All changes | includes/class-file-integrity.php +2 -116 3.0.02.11.12 View file →
@@ -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' ),