Plugin Directory

Changeset 2337484


Ignore:
Timestamp:
07/08/2020 03:05:56 PM (5 years ago)
Author:
wfmatt
Message:

7.4.9 - July 8, 2020

  • Improvement: Added list of known malicious usernames to suspicious administrator scan.
  • Improvement: Added ability for the WAF to determine if a given plugin/theme/core version is installed.
  • Improvement: Added a feature to export a diagnostics report.
  • Improvement: Add php_errorlog to the list of downloadable logs in diagnostics.
  • Improvement: Added a prompt to allow user to download a backup prior to repairing files.
  • Improvement: Prevent scan from failing when the home URL has changed and the key is no longer valid.
  • Improvement: Deprecated PHP 5.3, and ended PHP 5.2 support by prevent auto-update from running on older versions.
  • Fix: Fixed issue where WAF mysqli storage engine cannot find credentials if wflogs/ does not exist.
  • Fix: Changed capability checked to read WP REST API users endpoint when "Prevent discovery of usernames through ..." is enabled.
  • Fix: Prevented duplicate queries for wordfenceCentralConnected wfconfig value.
  • Fix: Prevented custom wp-content or other directories from appearing in "skipped paths" scan result, even when scanned.
  • Fix: Login Attempts dashboard widget "Show more" link is not visible when long usernames and IPs cause wrapping.
  • Fix: Fix typo in the readme.
Location:
wordfence
Files:
116 added
112 deleted
48 edited
1 copied

Legend:

Unmodified
Added
Removed
  • wordfence/tags/7.4.9/lib/menu_options.php

    r2290265 r2337484  
    163163                'wf-option-scansEnabled-suspiciousOptions' => __('Scan WordPress core, plugin, and theme options for known dangerous URLs and suspicious content', 'wordfence'),
    164164                'wf-option-scansEnabled-oldVersions' => __('Scan for out of date, abandoned, and vulnerable plugins, themes, and WordPress versions', 'wordfence'),
    165                 'wf-option-scansEnabled-suspiciousAdminUsers' => __('Scan for admin users created outside of WordPress', 'wordfence'),
     165                'wf-option-scansEnabled-suspiciousAdminUsers' => __('Scan for suspicious admin users created outside of WordPress', 'wordfence'),
    166166                'wf-option-scansEnabled-passwds' => __('Check the strength of passwords', 'wordfence'),
    167167                'wf-option-scansEnabled-diskSpace' => __('Monitor disk space', 'wordfence'),
  • wordfence/tags/7.4.9/lib/menu_scanner.php

    r2226721 r2337484  
    2121}
    2222?>
     23<div id="wordfenceMode_scan"></div>
    2324<div class="wrap wordfence">
    2425    <div class="wf-container-fluid">
  • wordfence/tags/7.4.9/lib/menu_tools_diagnostic.php

    r2131558 r2337484  
    4040                    <div id="sendByEmailDiv" class="wf-add-bottom">
    4141                        <span class="wf-nowrap">
    42                             <input class="wf-btn wf-btn-primary" type="submit" id="sendByEmail" value="Send Report by Email"/>
    43                             <input class="wf-btn wf-btn-default" type="button" id="expandAllDiagnostics" value="Expand All Diagnostics"/>
     42                            <input class="wf-btn wf-btn-primary wf-btn-sm" type="submit" id="exportDiagnostics" value="Export"/>
     43                            <input class="wf-btn wf-btn-primary wf-btn-sm" type="submit" id="sendByEmail" value="Send Report by Email"/>
     44                            <input class="wf-btn wf-btn-default wf-btn-sm" type="button" id="expandAllDiagnostics" value="Expand All Diagnostics"/>
    4445                        </span>
    4546                    </div>
  • wordfence/tags/7.4.9/lib/wfCentralAPI.php

    r2131558 r2337484  
    320320     */
    321321    public static function isConnected() {
    322         return self::isSupported() && ((bool) wfConfig::get('wordfenceCentralConnected', false));
     322        return self::isSupported() && ((bool) self::_isConnected());
    323323    }
    324324
     
    327327     */
    328328    public static function isPartialConnection() {
    329         return !wfConfig::get('wordfenceCentralConnected') && wfConfig::get('wordfenceCentralSiteID');
     329        return !self::_isConnected() && wfConfig::get('wordfenceCentralSiteID');
     330    }
     331
     332    public static function _isConnected($forceUpdate = false) {
     333        static $isConnected;
     334        if (!isset($isConnected) || $forceUpdate) {
     335            $isConnected = wfConfig::get('wordfenceCentralConnected', false);
     336        }
     337        return $isConnected;
    330338    }
    331339
  • wordfence/tags/7.4.9/lib/wfConfig.php

    r2290265 r2337484  
    225225        ),
    226226    );
    227     public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData', 'malwarePrefixes', 'coreHashes', 'noc1ScanSchedule', 'allScansScheduled', 'disclosureStates', 'scanStageStatuses', 'adminNoticeQueue');
     227    public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData', 'malwarePrefixes', 'coreHashes', 'noc1ScanSchedule', 'allScansScheduled', 'disclosureStates', 'scanStageStatuses', 'adminNoticeQueue', 'suspiciousAdminUsernames', 'wordpressPluginVersions', 'wordpressThemeVersions');
    228228    // Configuration keypairs that can be set from Central.
    229229    private static $wfCentralInternalConfig = array(
     
    932932    }
    933933    public static function autoUpdate(){
     934        // Prevent auto-update for PHP 5.2. Consider tying this into `wfVersionCheckController::PHP_DEPRECATING`.
     935        if (version_compare(PHP_VERSION, '5.3', '<')) {
     936            return;
     937        }
     938
    934939        if (!wfConfig::get('other_bypassLitespeedNoabort', false) && getenv('noabort') != '1' && stristr($_SERVER['SERVER_SOFTWARE'], 'litespeed') !== false) {
    935940            $lastEmail = self::get('lastLiteSpdEmail', false);
  • wordfence/tags/7.4.9/lib/wfDashboard.php

    r2025430 r2337484  
    225225
    226226        // Wordfence Central
    227         $this->wordfenceCentralConnected = wfConfig::get('wordfenceCentralConnected');
     227        $this->wordfenceCentralConnected = wfCentral::_isConnected(); // This value is cached.
    228228        $this->wordfenceCentralConnectTime = wfConfig::get('wordfenceCentralConnectTime');
    229229        $this->wordfenceCentralConnectEmail = wfConfig::get('wordfenceCentralConnectEmail');
  • wordfence/tags/7.4.9/lib/wfHelperString.php

    r1128972 r2337484  
    2020        return $return_val;
    2121    }
     22
     23    public static function plainTextTable($table) {
     24        if (count($table) === 0) {
     25            return '';
     26        }
     27        $colLengths = array();
     28        for ($row = 0; $row < count($table); $row++) {
     29            for ($col = 0; $col < count($table[$row]); $col++) {
     30                foreach (explode("\n", $table[$row][$col]) as $colText) {
     31                    if (!isset($colLengths[$col])) {
     32                        $colLengths[$col] = strlen($colText);
     33                        continue;
     34                    }
     35                    $len = strlen($colText);
     36                    if ($len > $colLengths[$col]) {
     37                        $colLengths[$col] = $len;
     38                    }
     39                }
     40            }
     41        }
     42        $hr = str_repeat('-', array_sum($colLengths) + (count($colLengths) * 3) + 1);
     43        $output = $hr . "\n";
     44        for ($row = 0; $row < count($table); $row++) {
     45            $colHeight = 0;
     46            for ($col = 0; $col < count($table[$row]); $col++) {
     47                $height = substr_count($table[$row][$col], "\n");
     48                if ($height > $colHeight) {
     49                    $colHeight = $height;
     50                }
     51            }
     52            for ($colRow = 0; $colRow <= $colHeight; $colRow++) {
     53                for ($col = 0; $col < count($table[$row]); $col++) {
     54                    $colRows = explode("\n", $table[$row][$col]);
     55                    $output .= '| ' . str_pad(isset($colRows[$colRow]) ? $colRows[$colRow] : '', $colLengths[$col], ' ', STR_PAD_RIGHT) . ' ';
     56                }
     57                $output .= "|\n";
     58            }
     59            if ($row === 0) {
     60                $output .= $hr . "\n";
     61            }
     62        }
     63        return trim($output . (count($table) > 1 ? $hr : ''));
     64    }
    2265}
  • wordfence/tags/7.4.9/lib/wfLog.php

    r2226721 r2337484  
    10571057class wfAdminUserMonitor {
    10581058
     1059    protected $currentAdminList = array();
     1060
    10591061    public function isEnabled() {
    10601062        $options = wfScanner::shared()->scanOptions();
     
    10741076    public function createInitialList() {
    10751077        $admins = $this->getCurrentAdmins();
    1076         wfConfig::set_ser('adminUserList', $admins);
     1078        $adminUserList = array();
     1079        foreach ($admins as $id => $user) {
     1080            $adminUserList[$id] = 1;
     1081        }
     1082        wfConfig::set_ser('adminUserList', $adminUserList);
    10771083    }
    10781084
     
    11361142
    11371143    /**
     1144     * @param bool $forceReload
    11381145     * @return array
    11391146     */
    1140     public function getCurrentAdmins() {
    1141         require_once(ABSPATH . WPINC . '/user.php');
    1142         if (is_multisite()) {
    1143             if (function_exists("get_sites")) {
    1144                 $sites = get_sites(array(
    1145                     'network_id' => null,
     1147    public function getCurrentAdmins($forceReload = false) {
     1148        if (empty($this->currentAdminList) || $forceReload) {
     1149            require_once(ABSPATH . WPINC . '/user.php');
     1150            if (is_multisite()) {
     1151                if (function_exists("get_sites")) {
     1152                    $sites = get_sites(array(
     1153                        'network_id' => null,
     1154                    ));
     1155                }
     1156                else {
     1157                    $sites = wp_get_sites(array(
     1158                        'network_id' => null,
     1159                    ));
     1160                }
     1161            } else {
     1162                $sites = array(array(
     1163                    'blog_id' => get_current_blog_id(),
    11461164                ));
    11471165            }
    1148             else {
    1149                 $sites = wp_get_sites(array(
    1150                     'network_id' => null,
     1166
     1167            // not very efficient, but the WordPress API doesn't provide a good way to do this.
     1168            $this->currentAdminList = array();
     1169            foreach ($sites as $siteRow) {
     1170                $siteRowArray = (array) $siteRow;
     1171                $user_query = new WP_User_Query(array(
     1172                    'blog_id' => $siteRowArray['blog_id'],
     1173                    'role'    => 'administrator',
    11511174                ));
    1152             }
    1153         } else {
    1154             $sites = array(array(
    1155                 'blog_id' => get_current_blog_id(),
    1156             ));
    1157         }
    1158 
    1159         // not very efficient, but the WordPress API doesn't provide a good way to do this.
    1160         $admins = array();
    1161         foreach ($sites as $siteRow) {
    1162             $siteRowArray = (array) $siteRow;
    1163             $user_query = new WP_User_Query(array(
    1164                 'blog_id' => $siteRowArray['blog_id'],
    1165                 'role'    => 'administrator',
    1166             ));
    1167             $users = $user_query->get_results();
    1168             if (is_array($users)) {
    1169                 /** @var WP_User $user */
    1170                 foreach ($users as $user) {
    1171                     $admins[$user->ID] = 1;
    1172                 }
    1173             }
    1174         }
    1175 
    1176         // Add any super admins that aren't also admins on a network
    1177         $superAdmins = get_super_admins();
    1178         foreach ($superAdmins as $userLogin) {
    1179             $user = get_user_by('login', $userLogin);
    1180             if ($user) {
    1181                 $admins[$user->ID] = 1;
    1182             }
    1183         }
    1184         return $admins;
     1175                $users = $user_query->get_results();
     1176                if (is_array($users)) {
     1177                    /** @var WP_User $user */
     1178                    foreach ($users as $user) {
     1179                        $this->currentAdminList[$user->ID] = $user;
     1180                    }
     1181                }
     1182            }
     1183
     1184            // Add any super admins that aren't also admins on a network
     1185            $superAdmins = get_super_admins();
     1186            foreach ($superAdmins as $userLogin) {
     1187                $user = get_user_by('login', $userLogin);
     1188                if ($user) {
     1189                    $this->currentAdminList[$user->ID] = $user;
     1190                }
     1191            }
     1192        }
     1193
     1194        return $this->currentAdminList;
    11851195    }
    11861196
     
    19952005        if (is_file($path)) {
    19962006            $file = basename($path);
    1997             if (preg_match('#(?:error_log(\-\d+)?$|\.log$)#i', $file)) {
     2007            if (preg_match('#(?:^php_errorlog$|error_log(\-\d+)?$|\.log$)#i', $file)) {
    19982008                return array($path => is_readable($path));
    19992009            }
  • wordfence/tags/7.4.9/lib/wfScan.php

    r2205414 r2337484  
    257257            self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
    258258            self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
     259
     260            if (preg_match('/The Wordfence API key you\'re using is already being used by: (\S*?) /', $e->getMessage(), $matches)) {
     261                wordfence::alert(__('Wordfence scan failed because of license site URL conflict', 'wordfence'), sprintf(__(<<<MSG
     262The Wordfence scan has failed because the Wordfence API key you're using is already being used by: %s
     263
     264If you have changed your blog URL, please sign-in to Wordfence, purchase a new key or reset an existing key, and then enter that key on this site's Wordfence Options page.
     265MSG
     266                    , 'wordfence'), $matches[1]), false);
     267            }
     268
    259269            exit();
    260270        }
  • wordfence/tags/7.4.9/lib/wfScanEngine.php

    r2290265 r2337484  
    815815                $fullFile = rtrim(ABSPATH, '/') . '/' . $file;
    816816                if (!wfUtils::fileTooBig($fullFile)) { //Silently ignore files that are too large for the purposes of inclusion in the scan issue
    817                     if (in_array($file, $base_abspath_relative) || (@is_file($fullFile) && @is_readable($fullFile))) {
     817                    if (in_array($file, $base_abspath_relative) || in_array($fullFile, $base_absolute) || (@is_file($fullFile) && @is_readable($fullFile))) {
    818818                        $scanned[] = realpath($fullFile);
    819819                    }
     
    18021802
    18031803        $adminUsers = new wfAdminUserMonitor();
    1804         if ($adminUsers->isEnabled() && $suspiciousAdmins = $adminUsers->checkNewAdmins()) {
    1805             foreach ($suspiciousAdmins as $userID) {
    1806                 $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
    1807                 $user = new WP_User($userID);
     1804        if ($adminUsers->isEnabled()) {
     1805            try {
     1806                $response = $this->api->call('suspicious_admin_usernames');
     1807                if (is_array($response) && isset($response['ok']) && wfUtils::truthyToBoolean($response['ok']) && !empty($response['patterns'])) {
     1808                    wfConfig::set_ser('suspiciousAdminUsernames', $response['patterns']);
     1809                }
     1810            } catch (Exception $e) {
     1811                // Let the rest of the scan continue
     1812            }
     1813
     1814            $suspiciousAdmins = $adminUsers->checkNewAdmins();
     1815            if (is_array($suspiciousAdmins)) {
     1816                foreach ($suspiciousAdmins as $userID) {
     1817                    $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
     1818                    $user = new WP_User($userID);
     1819                    $key = 'suspiciousAdminUsers' . $userID;
     1820                    $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
     1821                        sprintf(__("An admin user with the username %s was created outside of WordPress.", 'wordfence'), esc_html($user->user_login)),
     1822                        sprintf(__("An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($user->user_login)),
     1823                        array(
     1824                            'userID' => $userID,
     1825                        ));
     1826                    if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
     1827                    else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
     1828                }
     1829            }
     1830
     1831            $admins = $adminUsers->getCurrentAdmins();
     1832            /**
     1833             * @var WP_User $adminUser
     1834             */
     1835            foreach ($admins as $userID => $adminUser) {
     1836                $added = false;
    18081837                $key = 'suspiciousAdminUsers' . $userID;
    1809                 $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
    1810                     "An admin user with the username " . esc_html($user->user_login) . " was created outside of WordPress.",
    1811                     "An admin user with the username " . esc_html($user->user_login) . " was created outside of WordPress. It's
    1812                 possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove
    1813                 it.",
    1814                     array(
    1815                         'userID' => $userID,
    1816                     ));
     1838
     1839                // Check against user name list here.
     1840                $suspiciousAdminUsernames = wfConfig::get_ser('suspiciousAdminUsernames');
     1841                if (is_array($suspiciousAdminUsernames)) {
     1842                    foreach ($suspiciousAdminUsernames as $usernamePattern) {
     1843                        if (preg_match($usernamePattern, $adminUser->user_login)) {
     1844                            $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
     1845                                sprintf(__("An admin user with a suspicious username %s was found.", 'wordfence'), esc_html($adminUser->user_login)),
     1846                                sprintf(__("An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($adminUser->user_login)),
     1847                                array(
     1848                                    'userID' => $userID,
     1849                                ));
     1850                        }
     1851                    }
     1852                }
     1853
    18171854                if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
    18181855                else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
  • wordfence/tags/7.4.9/lib/wfSupportController.php

    r2226721 r2337484  
    148148    const ITEM_SCAN_RESULT_UNKNOWN_FILE_CORE = 'scan-result-unknown-file-in-wordpress-core';
    149149    const ITEM_SCAN_RESULT_SKIPPED_PATHS = 'scan-result-skipped-paths';
    150    
     150    const ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES = 'scan-result-repair-modified-files';
     151
    151152    const ITEM_TOOLS_TWO_FACTOR = 'tools-two-factor';
    152153    const ITEM_TOOLS_LIVE_TRAFFIC = 'tools-live-traffic';
     
    325326            case self::ITEM_SCAN_RESULT_UNKNOWN_FILE_CORE:
    326327            case self::ITEM_SCAN_RESULT_SKIPPED_PATHS:
    327                
     328            case self::ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES:
     329
    328330            case self::ITEM_TOOLS_TWO_FACTOR:
    329331            case self::ITEM_TOOLS_LIVE_TRAFFIC:
  • wordfence/tags/7.4.9/lib/wfUpdateCheck.php

    r2131558 r2337484  
    1010    private $theme_updates = array();
    1111    private $api = null;
     12
     13    public static function syncAllVersionInfo() {
     14        // Load the core/plugin/theme versions into the WAF configuration.
     15        wfConfig::set('wordpressVersion', wfUtils::getWPVersion());
     16        wfWAFConfig::set('wordpressVersion', wfUtils::getWPVersion(), wfWAF::getInstance(), 'synced');
     17
     18        if (!function_exists('get_plugins')) {
     19            require_once(ABSPATH . '/wp-admin/includes/plugin.php');
     20        }
     21
     22        $pluginVersions = array();
     23        foreach (get_plugins() as $pluginFile => $pluginData) {
     24            $slug = plugin_basename($pluginFile);
     25            if (preg_match('/^([^\/]+)\//', $pluginFile, $matches)) {
     26                $slug = $matches[1];
     27            } else if (preg_match('/^([^\/.]+)\.php$/', $pluginFile, $matches)) {
     28                $slug = $matches[1];
     29            }
     30            $pluginVersions[$slug] = isset($pluginData['Version']) ? $pluginData['Version'] : null;
     31        }
     32
     33        wfConfig::set_ser('wordpressPluginVersions', $pluginVersions);
     34        wfWAFConfig::set('wordpressPluginVersions', $pluginVersions, wfWAF::getInstance(), 'synced');
     35
     36        if (!function_exists('wp_get_themes')) {
     37            require_once(ABSPATH . '/wp-includes/theme.php');
     38        }
     39
     40        $themeVersions = array();
     41        foreach (wp_get_themes() as $slug => $theme) {
     42            $themeVersions[$slug] = isset($theme['Version']) ? $theme['Version'] : null;
     43        }
     44
     45        wfConfig::set_ser('wordpressThemeVersions', $themeVersions);
     46        wfWAFConfig::set('wordpressThemeVersions', $themeVersions, wfWAF::getInstance(), 'synced');
     47    }
    1248
    1349    public function __construct() {
  • wordfence/tags/7.4.9/lib/wfVersionCheckController.php

    r1879365 r2337484  
    66    const VERSION_UNSUPPORTED = 'unsupported';
    77   
    8     const PHP_DEPRECATING = '5.3.0'; //When greater than PHP_MINIMUM, will issue a discontinuing warning the first time we check it and find a version less than this (also applies to the other similar constant pairs)
    9     const PHP_MINIMUM = '5.2.0'; //The currently supported minimum
     8    const PHP_DEPRECATING = '5.5.0'; //When greater than PHP_MINIMUM, will issue a discontinuing warning the first time we check it and find a version less than this (also applies to the other similar constant pairs)
     9    const PHP_MINIMUM = '5.3.0'; //The currently supported minimum
    1010   
    1111    const OPENSSL_DEPRECATING = '1.0.1';
     
    4848                'phpVersionCheckDeprecationEmail_' . self::PHP_DEPRECATING,
    4949                __('PHP version too old', 'wordfence'),
    50                 sprintf(__('Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
     50                sprintf(__('Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
    5151            );
    5252           
     
    5454                'phpVersionCheckDeprecationNotice_' . self::PHP_DEPRECATING,
    5555                'phpVersionCheck',
    56                 sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
     56                sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
    5757            );
    5858        }
     
    6161                'phpVersionCheckUnsupportedEmail_' . self::PHP_MINIMUM,
    6262                __('PHP version too old', 'wordfence'),
    63                 sprintf(__('Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
     63                sprintf(__('Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
    6464            );
    6565           
     
    6767                'phpVersionCheckUnsupportedNotice_' . self::PHP_MINIMUM,
    6868                'phpVersionCheck',
    69                 sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
     69                sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
    7070            );
    7171        }
  • wordfence/tags/7.4.9/lib/wordfenceClass.php

    r2325400 r2337484  
    317317            wfScanEngine::startScan(false, wfScanner::SCAN_TYPE_QUICK);
    318318        }
    319        
     319
     320        wfUpdateCheck::syncAllVersionInfo();
     321
    320322        wfConfig::remove('lastPermissionsTemplateCheck');
    321323    }
     
    12791281       
    12801282        add_action('upgrader_process_complete', 'wordfence::_refreshVulnerabilityCache');
     1283        add_action('upgrader_process_complete', 'wfUpdateCheck::syncAllVersionInfo');
    12811284        add_action('upgrader_process_complete', 'wordfence::_scheduleRefreshUpdateNotification', 99, 2);
    12821285        add_action('wordfence_refreshUpdateNotification', 'wordfence::_refreshUpdateNotification', 99, 0);
     
    22232226                    'betaThreatDefenseFeed' => !!wfConfig::get('betaThreatDefenseFeed'),
    22242227                    'disableWAFIPBlocking' => wfConfig::get('disableWAFIPBlocking'),
     2228                    'wordpressVersion' => wfConfig::get('wordpressVersion'),
     2229                    'wordpressPluginVersions' => wfConfig::get_ser('wordpressPluginVersions'),
     2230                    'wordpressThemeVersions' => wfConfig::get_ser('wordpressThemeVersions'),
    22252231                );
    22262232                if (wfUtils::isAdmin()) {
     
    25292535    public static function jsonAPIAuthorFilter($response, $handler, $request) {
    25302536        $route = $request->get_route();
    2531         if (!current_user_can('list_users')) {
     2537        if (!current_user_can('edit_others_posts')) {
    25322538            $urlBase = wfWP_REST_Users_Controller::wfGetURLBase();
    25332539            if (preg_match('~' . preg_quote($urlBase, '~') . '/*$~i', $route)) {
     
    34913497        return compact('result');
    34923498    }
     3499    public static function ajax_exportDiagnostics_callback(){
     3500        add_filter('gettext', 'wordfence::_diagnosticsTranslationDisabler', 0, 3);
     3501
     3502        $url = site_url();
     3503        $url = preg_replace('/^https?:\/\//i', '', $url);
     3504        $url = preg_replace('/[^a-zA-Z0-9\.]+/', '_', $url);
     3505        $url = preg_replace('/^_+/', '', $url);
     3506        $url = preg_replace('/_+$/', '', $url);
     3507
     3508        header('Content-Type: application/octet-stream');
     3509        header('Content-Disposition: attachment; filename="diagnostics_for_' . $url . '.txt"');
     3510
     3511        echo wfView::create('diagnostics/text', array(
     3512            'diagnostic' => new wfDiagnostic,
     3513            'plugins' => get_plugins(),
     3514        ));
     3515        exit;
     3516    }
    34933517    public static function _diagnosticsTranslationDisabler($translation, $text, $domain) {
    34943518        return $text;
     
    58045828            'switchTo2FANew', 'switchTo2FAOld',
    58055829            'wfcentral_step1', 'wfcentral_step2', 'wfcentral_step3', 'wfcentral_step4', 'wfcentral_step5', 'wfcentral_step6', 'wfcentral_disconnect',
     5830            'exportDiagnostics',
    58065831        ) as $func){
    58075832            add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
     
    59045929            'modalHTMLTemplate' => wfView::create('common/modal-prompt', array('title' => '${title}', 'message' => '{{html message}}', 'primaryButton' => array('id' => 'wf-generic-modal-close', 'label' => __('Close', 'wordfence'), 'link' => '#')))->render(),
    59055930            'alertEmailBlacklist' => wfConfig::alertEmailBlacklist(),
     5931            'supportURLs' => array(
     5932                'scan-result-repair-modified-files' => esc_url_raw(wfSupportController::supportURL(wfSupportController::ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES)),
     5933            ),
    59065934            ));
    59075935    }
     
    75267554        $currentAutoPrependFile = ini_get('auto_prepend_file');
    75277555        $currentAutoPrepend = null;
    7528         if (isset($_POST['currentAutoPrepend']) && !WF_IS_WP_ENGINE) {
     7556        if (isset($_POST['currentAutoPrepend']) && !WF_IS_WP_ENGINE && !WF_IS_PRESSABLE) {
    75297557            $currentAutoPrepend = $_POST['currentAutoPrepend'];
    75307558        }
     
    76887716       
    76897717        try {
    7690             if ((!isset($_POST['iniModified']) || (isset($_POST['iniModified']) && !$_POST['iniModified']))) { //Uses .user.ini but not yet modified
     7718            if ((!isset($_POST['iniModified']) || (isset($_POST['iniModified']) && !$_POST['iniModified'])) && !WF_IS_PRESSABLE) { //Uses .user.ini but not yet modified
    76917719                $hasPreviousAutoPrepend = $helper->performIniRemoval($wp_filesystem);
    76927720               
     
    77297757            }
    77307758            else { //.user.ini and .htaccess modified if applicable and waiting period elapsed or otherwise ready to advance to next step
    7731                 if (WFWAF_AUTO_PREPEND && !WFWAF_SUBDIRECTORY_INSTALL && !WF_IS_WP_ENGINE) { //.user.ini modified, but the WAF is still enabled
     7759                if (WFWAF_AUTO_PREPEND && !WFWAF_SUBDIRECTORY_INSTALL && !WF_IS_WP_ENGINE && !WF_IS_PRESSABLE) { //.user.ini modified, but the WAF is still enabled
    77327760                    $retryAttempted = (isset($_POST['retryAttempted']) && $_POST['retryAttempted']);
    77337761                    $userIniError = '<p class="wf-error">';
     
    84898517
    84908518    public static function getWAFBootstrapPath() {
     8519        if (WF_IS_PRESSABLE) {
     8520            return WP_CONTENT_DIR . '/wordfence-waf.php';
     8521        }
    84918522        return ABSPATH . 'wordfence-waf.php';
    84928523    }
  • wordfence/tags/7.4.9/modules/login-security/wordfence-login-security.php

    r2325400 r2337484  
    2828   
    2929    define('WORDFENCE_LS_VERSION', '1.0.5');
    30     define('WORDFENCE_LS_BUILD_NUMBER', '1592338782');
     30    define('WORDFENCE_LS_BUILD_NUMBER', '1594219913');
    3131   
    3232    if (!defined('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES')) { define('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES', 15); }
  • wordfence/tags/7.4.9/readme.txt

    r2325413 r2337484  
    55Requires PHP: 5.3
    66Tested up to: 5.4
    7 Stable tag: 7.4.8
     7Stable tag: 7.4.9
    88
    99Secure your website with the most comprehensive WordPress security plugin. Firewall, malware scan, blocking, live traffic, login security & more.
     
    184184== Changelog ==
    185185
     186= 7.4.9 - July 8, 2020 =
     187
     188* Improvement: Added list of known malicious usernames to suspicious administrator scan.
     189* Improvement: Added ability for the WAF to determine if a given plugin/theme/core version is installed.
     190* Improvement: Added a feature to export a diagnostics report.
     191* Improvement: Add php_errorlog to the list of downloadable logs in diagnostics.
     192* Improvement: Added a prompt to allow user to download a backup prior to repairing files.
     193* Improvement: Prevent scan from failing when the home URL has changed and the key is no longer valid.
     194* Improvement: Deprecated PHP 5.3, and ended PHP 5.2 support by prevent auto-update from running on older versions.
     195* Fix: Fixed issue where WAF mysqli storage engine cannot find credentials if wflogs/ does not exist.
     196* Fix: Changed capability checked to read WP REST API users endpoint when "Prevent discovery of usernames through ..." is enabled.
     197* Fix: Prevented duplicate queries for wordfenceCentralConnected wfconfig value.
     198* Fix: Prevented custom wp-content or other directories from appearing in "skipped paths" scan result, even when scanned.
     199* Fix: Login Attempts dashboard widget "Show more" link is not visible when long usernames and IPs cause wrapping.
     200* Fix: Fix typo in the readme.
     201
    186202= 7.4.8 - June 16, 2020 =
    187203* Fix: Fixed issue with fatal errors encountered during activation under certain conditions.
     
    194210* Improvement: Added the state/province name when applicable to geolocation displays in Live Traffic.
    195211* Improvement: New blocking page design to better inform blocked visitors on how to resolve the block.
    196 * Improvement: Custom WP_CONTENT_DIR, WP_PLUGIN_DUR, and UPLOADS path constants will now get scanned correctly.
     212* Improvement: Custom WP_CONTENT_DIR, WP_PLUGIN_DIR, and UPLOADS path constants will now get scanned correctly.
    197213* Improvement: Added TLS connection failure detection to brute force reporting and checking and a corresponding backoff period.
    198214* Fix: Fixed an issue where a bad cron record could interfere with automatic WAF rule updates.
  • wordfence/tags/7.4.9/vendor/wordfence/wf-waf/src/init.php

    r2143823 r2337484  
    66define('WFWAF_LIB_PATH', WFWAF_PATH . 'lib/');
    77define('WFWAF_VIEW_PATH', WFWAF_PATH . 'views/');
    8 define('WFWAF_API_URL_SEC', 'https://noc4.wordfence.com/v1.8/');
     8define('WFWAF_API_URL_SEC', 'https://noc4.wordfence.com/v1.9/');
    99if (!defined('WFWAF_DEBUG')) {
    1010    define('WFWAF_DEBUG', false);
  • wordfence/tags/7.4.9/vendor/wordfence/wf-waf/src/lib/rules.php

    r2226721 r2337484  
    497497        'urlschemematches',
    498498        'urlschemenotmatches',
     499        'versionequals',
     500        'versionnotequals',
     501        'versiongreaterthan',
     502        'versiongreaterthanequalto',
     503        'versionlessthan',
     504        'versionlessthanequalto',
    499505    );
    500506
     
    11321138    }
    11331139
     1140    public function versionEquals($subject) {
     1141        if ($subject === null) {
     1142            return false;
     1143        }
     1144        return version_compare($subject, $this->getExpected(), '==');
     1145    }
     1146
     1147    public function versionNotEquals($subject) {
     1148        if ($subject === null) {
     1149            return false;
     1150        }
     1151        return version_compare($subject, $this->getExpected(), '!=');
     1152    }
     1153
     1154    public function versionGreaterThan($subject) {
     1155        if ($subject === null) {
     1156            return false;
     1157        }
     1158        return version_compare($subject, $this->getExpected(), '>');
     1159    }
     1160
     1161    public function versionGreaterThanEqualTo($subject) {
     1162        if ($subject === null) {
     1163            return false;
     1164        }
     1165        return version_compare($subject, $this->getExpected(), '>=');
     1166    }
     1167
     1168    public function versionLessThan($subject) {
     1169        if ($subject === null) {
     1170            return false;
     1171        }
     1172        return version_compare($subject, $this->getExpected(), '<');
     1173    }
     1174
     1175    public function versionLessThanEqualTo($subject) {
     1176        if ($subject === null) {
     1177            return false;
     1178        }
     1179        return version_compare($subject, $this->getExpected(), '<=');
     1180    }
     1181
    11341182    /**
    11351183     * @return mixed
  • wordfence/tags/7.4.9/views/scanner/issue-control-repair.php

    r1808795 r2337484  
    22if (!defined('WORDFENCE_VERSION')) { exit; }
    33?>
    4 {{if data.canFix}}<a href="#" class="wf-issue-control wf-issue-control-repair"><svg class="wf-issue-control-icon" viewBox="0 0 106.7 106.7"><path d="M104.94,18.77a4,4,0,0,0-1.17-2.93L90.86,2.93a4.25,4.25,0,0,0-5.87,0L1.17,86.75a4.25,4.25,0,0,0,0,5.86l12.91,12.91A4,4,0,0,0,17,106.7a4,4,0,0,0,2.93-1.17L103.77,21.7a4,4,0,0,0,1.17-2.93ZM75.8,37.87l-7-7,19.1-19.1,7,7Zm0,0"/><path d="M14.93,16.68l2-6.39,6.39-2-6.39-2L14.93,0,13,6.39l-6.39,2,6.39,2Zm0,0"/><path d="M31.87,24.77l3.91,12.77L39.7,24.77l12.77-3.91L39.7,16.95,35.78,4.17,31.87,16.95,19.1,20.86Zm0,0"/><path d="M100.31,48.1l-2-6.39-2,6.39-6.39,2,6.39,2,2,6.39,2-6.39,6.39-2Zm0,0"/><path d="M56.64,16.68l2-6.39,6.39-2-6.39-2L56.64,0l-2,6.39-6.39,2,6.39,2Zm0,0"/></svg><span class="wf-issue-control-label"><?php _e('Repair', 'wordfence'); ?></span></a>{{/if}}
     4{{if data.canFix}}<a href="#" class="wf-issue-control wf-issue-control-repair" data-file="${data.file}"><svg class="wf-issue-control-icon" viewBox="0 0 106.7 106.7"><path d="M104.94,18.77a4,4,0,0,0-1.17-2.93L90.86,2.93a4.25,4.25,0,0,0-5.87,0L1.17,86.75a4.25,4.25,0,0,0,0,5.86l12.91,12.91A4,4,0,0,0,17,106.7a4,4,0,0,0,2.93-1.17L103.77,21.7a4,4,0,0,0,1.17-2.93ZM75.8,37.87l-7-7,19.1-19.1,7,7Zm0,0"/><path d="M14.93,16.68l2-6.39,6.39-2-6.39-2L14.93,0,13,6.39l-6.39,2,6.39,2Zm0,0"/><path d="M31.87,24.77l3.91,12.77L39.7,24.77l12.77-3.91L39.7,16.95,35.78,4.17,31.87,16.95,19.1,20.86Zm0,0"/><path d="M100.31,48.1l-2-6.39-2,6.39-6.39,2,6.39,2,2,6.39,2-6.39,6.39-2Zm0,0"/><path d="M56.64,16.68l2-6.39,6.39-2-6.39-2L56.64,0l-2,6.39-6.39,2,6.39,2Zm0,0"/></svg><span class="wf-issue-control-label"><?php _e('Repair', 'wordfence'); ?></span></a>{{/if}}
  • wordfence/tags/7.4.9/views/scanner/options-group-general.php

    r2187129 r2337484  
    4747                        array('key' => 'scansEnabled_suspiciousOptions', 'label' => __('Scan WordPress core, plugin, and theme options for known dangerous URLs and suspicious content', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_MALWARE_OPTIONS)),
    4848                        array('key' => 'scansEnabled_oldVersions', 'label' => __('Scan for out of date, abandoned, and vulnerable plugins, themes, and WordPress versions', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_UPDATES)),
    49                         array('key' => 'scansEnabled_suspiciousAdminUsers', 'label' => __('Scan for admin users created outside of WordPress', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_UNKNOWN_ADMINS)),
     49                        array('key' => 'scansEnabled_suspiciousAdminUsers', 'label' => __('Scan for suspicious admin users created outside of WordPress', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_UNKNOWN_ADMINS)),
    5050                        array('key' => 'scansEnabled_passwds', 'label' => __('Check the strength of passwords', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_PASSWORD_STRENGTH)),
    5151                        array('key' => 'scansEnabled_diskSpace', 'label' => __('Monitor disk space', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_DISK_SPACE)),
  • wordfence/tags/7.4.9/views/waf/waf-install.php

    r2143823 r2337484  
    1818            <?php
    1919            $currentAutoPrependFile = ini_get('auto_prepend_file');
    20             if (empty($currentAutoPrependFile) || WF_IS_WP_ENGINE):
     20            if (empty($currentAutoPrependFile) || WF_IS_WP_ENGINE || WF_IS_PRESSABLE):
    2121            ?>
    2222            <p><?php _e('To make your site as secure as possible, the Wordfence Web Application Firewall is designed to run via a PHP setting called <code>auto_prepend_file</code>, which ensures it runs before any potentially vulnerable code runs.', 'wordfence'); ?></p>
  • wordfence/tags/7.4.9/views/waf/waf-uninstall.php

    r2143823 r2337484  
    1717        <div class="wf-modal-content">
    1818        <?php
    19         if (WF_IS_WP_ENGINE) {
     19        if (WF_IS_WP_ENGINE || WF_IS_PRESSABLE) {
    2020            $currentAutoPrependFile = wordfence::getWAFBootstrapPath();
    2121        } else {
  • wordfence/tags/7.4.9/waf/bootstrap.php

    r2290265 r2337484  
    1212if (!defined('WF_IS_WP_ENGINE')) {
    1313    define('WF_IS_WP_ENGINE', isset($_SERVER['IS_WPE']));
     14}
     15if (!defined('WF_IS_PRESSABLE')) {
     16    define('WF_IS_PRESSABLE', (defined('IS_ATOMIC') && IS_ATOMIC) || (defined('IS_PRESSABLE') && IS_PRESSABLE));
    1417}
    1518
     
    693696        @chmod(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', (wfWAFWordPress::permissions() | 0444));
    694697    }
     698
     699    public function getGlobal($global) {
     700        if (wfWAFUtils::strpos($global, '.') === false) {
     701            return null;
     702        }
     703        list($prefix, $_global) = explode('.', $global);
     704        switch ($prefix) {
     705            case 'wordpress':
     706                if ($_global === 'core') {
     707                    return $this->getStorageEngine()->getConfig('wordpressVersion', null, 'synced');
     708                } else if ($_global === 'plugins') {
     709                    return $this->getStorageEngine()->getConfig('wordpressPluginVersions', null, 'synced');
     710                } else if ($_global === 'themes') {
     711                    return $this->getStorageEngine()->getConfig('wordpressThemeVersions', null, 'synced');
     712                }
     713                break;
     714        }
     715        return parent::getGlobal($global);
     716    }
     717}
     718
     719class wfWAFWordPressStorageMySQL extends wfWAFStorageMySQL {
     720
     721    public function getSerializedParams() {
     722        $params = parent::getSerializedParams();
     723        $params[] = 'wordpressPluginVersions';
     724        $params[] = 'wordpressThemeVersions';
     725        return $params;
     726    }
     727
     728    public function getAutoloadParams() {
     729        $params = parent::getAutoloadParams();
     730        $params['synced'][] = 'wordpressVersion';
     731        $params['synced'][] = 'wordpressPluginVersions';
     732        $params['synced'][] = 'wordpressThemeVersions';
     733        return $params;
     734    }
    695735}
    696736
     
    718758            case 'mysqli':
    719759                // Find the wp-config.php
    720                 if (file_exists(dirname(WFWAF_LOG_PATH) . '/../wp-config.php')) {
    721                     $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(WFWAF_LOG_PATH . '/../../wp-config.php');
    722                 } else if (file_exists(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php')) {
    723                     $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(WFWAF_LOG_PATH . '/../../../wp-config.php');
     760                if (is_dir(dirname(WFWAF_LOG_PATH))) {
     761                    if (file_exists(dirname(WFWAF_LOG_PATH) . '/../wp-config.php')) {
     762                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(dirname(WFWAF_LOG_PATH) . '/../wp-config.php');
     763                    } else if (file_exists(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php')) {
     764                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php');
     765                    }
     766                } else if (!empty($_SERVER['DOCUMENT_ROOT'])) {
     767                    if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php')) {
     768                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php');
     769                    } else if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/../wp-config.php')) {
     770                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig($_SERVER['DOCUMENT_ROOT'] . '/../wp-config.php');
     771                    }
    724772                }
    725773
    726774                if (!empty($wfWAFDBCredentials)) {
    727                     $wfWAFStorageEngine = new wfWAFStorageMySQL(new wfWAFStorageEngineMySQLi(), $wfWAFDBCredentials['tablePrefix']);
     775                    $wfWAFStorageEngine = new wfWAFWordPressStorageMySQL(new wfWAFStorageEngineMySQLi(), $wfWAFDBCredentials['tablePrefix']);
    728776                    $wfWAFStorageEngine->getDb()->connect(
    729777                        $wfWAFDBCredentials['user'],
  • wordfence/tags/7.4.9/wordfence.php

    r2325400 r2337484  
    55Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
    66Author: Wordfence
    7 Version: 7.4.8
     7Version: 7.4.9
    88Author URI: http://www.wordfence.com/
    99Network: true
     
    1616    exit;
    1717}
    18 define('WORDFENCE_VERSION', '7.4.8');
    19 define('WORDFENCE_BUILD_NUMBER', '1592338782');
     18define('WORDFENCE_VERSION', '7.4.9');
     19define('WORDFENCE_BUILD_NUMBER', '1594219913');
    2020define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
    2121    basename(dirname(__FILE__)) . '/' . basename(__FILE__));
     
    3737if (!defined('WF_IS_WP_ENGINE')) {
    3838    define('WF_IS_WP_ENGINE', isset($_SERVER['IS_WPE']));
     39}
     40if (!defined('WF_IS_PRESSABLE')) {
     41    define('WF_IS_PRESSABLE', (defined('IS_ATOMIC') && IS_ATOMIC) || (defined('IS_PRESSABLE') && IS_PRESSABLE));
    3942}
    4043
  • wordfence/trunk/lib/menu_options.php

    r2290265 r2337484  
    163163                'wf-option-scansEnabled-suspiciousOptions' => __('Scan WordPress core, plugin, and theme options for known dangerous URLs and suspicious content', 'wordfence'),
    164164                'wf-option-scansEnabled-oldVersions' => __('Scan for out of date, abandoned, and vulnerable plugins, themes, and WordPress versions', 'wordfence'),
    165                 'wf-option-scansEnabled-suspiciousAdminUsers' => __('Scan for admin users created outside of WordPress', 'wordfence'),
     165                'wf-option-scansEnabled-suspiciousAdminUsers' => __('Scan for suspicious admin users created outside of WordPress', 'wordfence'),
    166166                'wf-option-scansEnabled-passwds' => __('Check the strength of passwords', 'wordfence'),
    167167                'wf-option-scansEnabled-diskSpace' => __('Monitor disk space', 'wordfence'),
  • wordfence/trunk/lib/menu_scanner.php

    r2226721 r2337484  
    2121}
    2222?>
     23<div id="wordfenceMode_scan"></div>
    2324<div class="wrap wordfence">
    2425    <div class="wf-container-fluid">
  • wordfence/trunk/lib/menu_tools_diagnostic.php

    r2131558 r2337484  
    4040                    <div id="sendByEmailDiv" class="wf-add-bottom">
    4141                        <span class="wf-nowrap">
    42                             <input class="wf-btn wf-btn-primary" type="submit" id="sendByEmail" value="Send Report by Email"/>
    43                             <input class="wf-btn wf-btn-default" type="button" id="expandAllDiagnostics" value="Expand All Diagnostics"/>
     42                            <input class="wf-btn wf-btn-primary wf-btn-sm" type="submit" id="exportDiagnostics" value="Export"/>
     43                            <input class="wf-btn wf-btn-primary wf-btn-sm" type="submit" id="sendByEmail" value="Send Report by Email"/>
     44                            <input class="wf-btn wf-btn-default wf-btn-sm" type="button" id="expandAllDiagnostics" value="Expand All Diagnostics"/>
    4445                        </span>
    4546                    </div>
  • wordfence/trunk/lib/wfCentralAPI.php

    r2131558 r2337484  
    320320     */
    321321    public static function isConnected() {
    322         return self::isSupported() && ((bool) wfConfig::get('wordfenceCentralConnected', false));
     322        return self::isSupported() && ((bool) self::_isConnected());
    323323    }
    324324
     
    327327     */
    328328    public static function isPartialConnection() {
    329         return !wfConfig::get('wordfenceCentralConnected') && wfConfig::get('wordfenceCentralSiteID');
     329        return !self::_isConnected() && wfConfig::get('wordfenceCentralSiteID');
     330    }
     331
     332    public static function _isConnected($forceUpdate = false) {
     333        static $isConnected;
     334        if (!isset($isConnected) || $forceUpdate) {
     335            $isConnected = wfConfig::get('wordfenceCentralConnected', false);
     336        }
     337        return $isConnected;
    330338    }
    331339
  • wordfence/trunk/lib/wfConfig.php

    r2290265 r2337484  
    225225        ),
    226226    );
    227     public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData', 'malwarePrefixes', 'coreHashes', 'noc1ScanSchedule', 'allScansScheduled', 'disclosureStates', 'scanStageStatuses', 'adminNoticeQueue');
     227    public static $serializedOptions = array('lastAdminLogin', 'scanSched', 'emailedIssuesList', 'wf_summaryItems', 'adminUserList', 'twoFactorUsers', 'alertFreqTrack', 'wfStatusStartMsgs', 'vulnerabilities_plugin', 'vulnerabilities_theme', 'dashboardData', 'malwarePrefixes', 'coreHashes', 'noc1ScanSchedule', 'allScansScheduled', 'disclosureStates', 'scanStageStatuses', 'adminNoticeQueue', 'suspiciousAdminUsernames', 'wordpressPluginVersions', 'wordpressThemeVersions');
    228228    // Configuration keypairs that can be set from Central.
    229229    private static $wfCentralInternalConfig = array(
     
    932932    }
    933933    public static function autoUpdate(){
     934        // Prevent auto-update for PHP 5.2. Consider tying this into `wfVersionCheckController::PHP_DEPRECATING`.
     935        if (version_compare(PHP_VERSION, '5.3', '<')) {
     936            return;
     937        }
     938
    934939        if (!wfConfig::get('other_bypassLitespeedNoabort', false) && getenv('noabort') != '1' && stristr($_SERVER['SERVER_SOFTWARE'], 'litespeed') !== false) {
    935940            $lastEmail = self::get('lastLiteSpdEmail', false);
  • wordfence/trunk/lib/wfDashboard.php

    r2025430 r2337484  
    225225
    226226        // Wordfence Central
    227         $this->wordfenceCentralConnected = wfConfig::get('wordfenceCentralConnected');
     227        $this->wordfenceCentralConnected = wfCentral::_isConnected(); // This value is cached.
    228228        $this->wordfenceCentralConnectTime = wfConfig::get('wordfenceCentralConnectTime');
    229229        $this->wordfenceCentralConnectEmail = wfConfig::get('wordfenceCentralConnectEmail');
  • wordfence/trunk/lib/wfHelperString.php

    r1128972 r2337484  
    2020        return $return_val;
    2121    }
     22
     23    public static function plainTextTable($table) {
     24        if (count($table) === 0) {
     25            return '';
     26        }
     27        $colLengths = array();
     28        for ($row = 0; $row < count($table); $row++) {
     29            for ($col = 0; $col < count($table[$row]); $col++) {
     30                foreach (explode("\n", $table[$row][$col]) as $colText) {
     31                    if (!isset($colLengths[$col])) {
     32                        $colLengths[$col] = strlen($colText);
     33                        continue;
     34                    }
     35                    $len = strlen($colText);
     36                    if ($len > $colLengths[$col]) {
     37                        $colLengths[$col] = $len;
     38                    }
     39                }
     40            }
     41        }
     42        $hr = str_repeat('-', array_sum($colLengths) + (count($colLengths) * 3) + 1);
     43        $output = $hr . "\n";
     44        for ($row = 0; $row < count($table); $row++) {
     45            $colHeight = 0;
     46            for ($col = 0; $col < count($table[$row]); $col++) {
     47                $height = substr_count($table[$row][$col], "\n");
     48                if ($height > $colHeight) {
     49                    $colHeight = $height;
     50                }
     51            }
     52            for ($colRow = 0; $colRow <= $colHeight; $colRow++) {
     53                for ($col = 0; $col < count($table[$row]); $col++) {
     54                    $colRows = explode("\n", $table[$row][$col]);
     55                    $output .= '| ' . str_pad(isset($colRows[$colRow]) ? $colRows[$colRow] : '', $colLengths[$col], ' ', STR_PAD_RIGHT) . ' ';
     56                }
     57                $output .= "|\n";
     58            }
     59            if ($row === 0) {
     60                $output .= $hr . "\n";
     61            }
     62        }
     63        return trim($output . (count($table) > 1 ? $hr : ''));
     64    }
    2265}
  • wordfence/trunk/lib/wfLog.php

    r2226721 r2337484  
    10571057class wfAdminUserMonitor {
    10581058
     1059    protected $currentAdminList = array();
     1060
    10591061    public function isEnabled() {
    10601062        $options = wfScanner::shared()->scanOptions();
     
    10741076    public function createInitialList() {
    10751077        $admins = $this->getCurrentAdmins();
    1076         wfConfig::set_ser('adminUserList', $admins);
     1078        $adminUserList = array();
     1079        foreach ($admins as $id => $user) {
     1080            $adminUserList[$id] = 1;
     1081        }
     1082        wfConfig::set_ser('adminUserList', $adminUserList);
    10771083    }
    10781084
     
    11361142
    11371143    /**
     1144     * @param bool $forceReload
    11381145     * @return array
    11391146     */
    1140     public function getCurrentAdmins() {
    1141         require_once(ABSPATH . WPINC . '/user.php');
    1142         if (is_multisite()) {
    1143             if (function_exists("get_sites")) {
    1144                 $sites = get_sites(array(
    1145                     'network_id' => null,
     1147    public function getCurrentAdmins($forceReload = false) {
     1148        if (empty($this->currentAdminList) || $forceReload) {
     1149            require_once(ABSPATH . WPINC . '/user.php');
     1150            if (is_multisite()) {
     1151                if (function_exists("get_sites")) {
     1152                    $sites = get_sites(array(
     1153                        'network_id' => null,
     1154                    ));
     1155                }
     1156                else {
     1157                    $sites = wp_get_sites(array(
     1158                        'network_id' => null,
     1159                    ));
     1160                }
     1161            } else {
     1162                $sites = array(array(
     1163                    'blog_id' => get_current_blog_id(),
    11461164                ));
    11471165            }
    1148             else {
    1149                 $sites = wp_get_sites(array(
    1150                     'network_id' => null,
     1166
     1167            // not very efficient, but the WordPress API doesn't provide a good way to do this.
     1168            $this->currentAdminList = array();
     1169            foreach ($sites as $siteRow) {
     1170                $siteRowArray = (array) $siteRow;
     1171                $user_query = new WP_User_Query(array(
     1172                    'blog_id' => $siteRowArray['blog_id'],
     1173                    'role'    => 'administrator',
    11511174                ));
    1152             }
    1153         } else {
    1154             $sites = array(array(
    1155                 'blog_id' => get_current_blog_id(),
    1156             ));
    1157         }
    1158 
    1159         // not very efficient, but the WordPress API doesn't provide a good way to do this.
    1160         $admins = array();
    1161         foreach ($sites as $siteRow) {
    1162             $siteRowArray = (array) $siteRow;
    1163             $user_query = new WP_User_Query(array(
    1164                 'blog_id' => $siteRowArray['blog_id'],
    1165                 'role'    => 'administrator',
    1166             ));
    1167             $users = $user_query->get_results();
    1168             if (is_array($users)) {
    1169                 /** @var WP_User $user */
    1170                 foreach ($users as $user) {
    1171                     $admins[$user->ID] = 1;
    1172                 }
    1173             }
    1174         }
    1175 
    1176         // Add any super admins that aren't also admins on a network
    1177         $superAdmins = get_super_admins();
    1178         foreach ($superAdmins as $userLogin) {
    1179             $user = get_user_by('login', $userLogin);
    1180             if ($user) {
    1181                 $admins[$user->ID] = 1;
    1182             }
    1183         }
    1184         return $admins;
     1175                $users = $user_query->get_results();
     1176                if (is_array($users)) {
     1177                    /** @var WP_User $user */
     1178                    foreach ($users as $user) {
     1179                        $this->currentAdminList[$user->ID] = $user;
     1180                    }
     1181                }
     1182            }
     1183
     1184            // Add any super admins that aren't also admins on a network
     1185            $superAdmins = get_super_admins();
     1186            foreach ($superAdmins as $userLogin) {
     1187                $user = get_user_by('login', $userLogin);
     1188                if ($user) {
     1189                    $this->currentAdminList[$user->ID] = $user;
     1190                }
     1191            }
     1192        }
     1193
     1194        return $this->currentAdminList;
    11851195    }
    11861196
     
    19952005        if (is_file($path)) {
    19962006            $file = basename($path);
    1997             if (preg_match('#(?:error_log(\-\d+)?$|\.log$)#i', $file)) {
     2007            if (preg_match('#(?:^php_errorlog$|error_log(\-\d+)?$|\.log$)#i', $file)) {
    19982008                return array($path => is_readable($path));
    19992009            }
  • wordfence/trunk/lib/wfScan.php

    r2205414 r2337484  
    257257            self::status(2, 'info', "Wordfence used " . wfUtils::formatBytes($peakMemory - self::$peakMemAtStart) . " of memory for scan. Server peak memory usage was: " . wfUtils::formatBytes($peakMemory));
    258258            self::status(2, 'error', "Scan terminated with error: " . $e->getMessage());
     259
     260            if (preg_match('/The Wordfence API key you\'re using is already being used by: (\S*?) /', $e->getMessage(), $matches)) {
     261                wordfence::alert(__('Wordfence scan failed because of license site URL conflict', 'wordfence'), sprintf(__(<<<MSG
     262The Wordfence scan has failed because the Wordfence API key you're using is already being used by: %s
     263
     264If you have changed your blog URL, please sign-in to Wordfence, purchase a new key or reset an existing key, and then enter that key on this site's Wordfence Options page.
     265MSG
     266                    , 'wordfence'), $matches[1]), false);
     267            }
     268
    259269            exit();
    260270        }
  • wordfence/trunk/lib/wfScanEngine.php

    r2290265 r2337484  
    815815                $fullFile = rtrim(ABSPATH, '/') . '/' . $file;
    816816                if (!wfUtils::fileTooBig($fullFile)) { //Silently ignore files that are too large for the purposes of inclusion in the scan issue
    817                     if (in_array($file, $base_abspath_relative) || (@is_file($fullFile) && @is_readable($fullFile))) {
     817                    if (in_array($file, $base_abspath_relative) || in_array($fullFile, $base_absolute) || (@is_file($fullFile) && @is_readable($fullFile))) {
    818818                        $scanned[] = realpath($fullFile);
    819819                    }
     
    18021802
    18031803        $adminUsers = new wfAdminUserMonitor();
    1804         if ($adminUsers->isEnabled() && $suspiciousAdmins = $adminUsers->checkNewAdmins()) {
    1805             foreach ($suspiciousAdmins as $userID) {
    1806                 $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
    1807                 $user = new WP_User($userID);
     1804        if ($adminUsers->isEnabled()) {
     1805            try {
     1806                $response = $this->api->call('suspicious_admin_usernames');
     1807                if (is_array($response) && isset($response['ok']) && wfUtils::truthyToBoolean($response['ok']) && !empty($response['patterns'])) {
     1808                    wfConfig::set_ser('suspiciousAdminUsernames', $response['patterns']);
     1809                }
     1810            } catch (Exception $e) {
     1811                // Let the rest of the scan continue
     1812            }
     1813
     1814            $suspiciousAdmins = $adminUsers->checkNewAdmins();
     1815            if (is_array($suspiciousAdmins)) {
     1816                foreach ($suspiciousAdmins as $userID) {
     1817                    $this->scanController->incrementSummaryItem(wfScanner::SUMMARY_SCANNED_USERS);
     1818                    $user = new WP_User($userID);
     1819                    $key = 'suspiciousAdminUsers' . $userID;
     1820                    $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
     1821                        sprintf(__("An admin user with the username %s was created outside of WordPress.", 'wordfence'), esc_html($user->user_login)),
     1822                        sprintf(__("An admin user with the username %s was created outside of WordPress. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($user->user_login)),
     1823                        array(
     1824                            'userID' => $userID,
     1825                        ));
     1826                    if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
     1827                    else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
     1828                }
     1829            }
     1830
     1831            $admins = $adminUsers->getCurrentAdmins();
     1832            /**
     1833             * @var WP_User $adminUser
     1834             */
     1835            foreach ($admins as $userID => $adminUser) {
     1836                $added = false;
    18081837                $key = 'suspiciousAdminUsers' . $userID;
    1809                 $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
    1810                     "An admin user with the username " . esc_html($user->user_login) . " was created outside of WordPress.",
    1811                     "An admin user with the username " . esc_html($user->user_login) . " was created outside of WordPress. It's
    1812                 possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove
    1813                 it.",
    1814                     array(
    1815                         'userID' => $userID,
    1816                     ));
     1838
     1839                // Check against user name list here.
     1840                $suspiciousAdminUsernames = wfConfig::get_ser('suspiciousAdminUsernames');
     1841                if (is_array($suspiciousAdminUsernames)) {
     1842                    foreach ($suspiciousAdminUsernames as $usernamePattern) {
     1843                        if (preg_match($usernamePattern, $adminUser->user_login)) {
     1844                            $added = $this->addIssue('suspiciousAdminUsers', wfIssues::SEVERITY_HIGH, $key, $key,
     1845                                sprintf(__("An admin user with a suspicious username %s was found.", 'wordfence'), esc_html($adminUser->user_login)),
     1846                                sprintf(__("An admin user with a suspicious username %s was found. Administrators accounts with usernames similar to this are commonly seen created by hackers. It's possible a plugin could have created the account, but if you do not recognize the user, we suggest you remove it.", 'wordfence'), esc_html($adminUser->user_login)),
     1847                                array(
     1848                                    'userID' => $userID,
     1849                                ));
     1850                        }
     1851                    }
     1852                }
     1853
    18171854                if ($added == wfIssues::ISSUE_ADDED || $added == wfIssues::ISSUE_UPDATED) { $haveIssues = wfIssues::STATUS_PROBLEM; }
    18181855                else if ($haveIssues != wfIssues::STATUS_PROBLEM && ($added == wfIssues::ISSUE_IGNOREP || $added == wfIssues::ISSUE_IGNOREC)) { $haveIssues = wfIssues::STATUS_IGNORED; }
  • wordfence/trunk/lib/wfSupportController.php

    r2226721 r2337484  
    148148    const ITEM_SCAN_RESULT_UNKNOWN_FILE_CORE = 'scan-result-unknown-file-in-wordpress-core';
    149149    const ITEM_SCAN_RESULT_SKIPPED_PATHS = 'scan-result-skipped-paths';
    150    
     150    const ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES = 'scan-result-repair-modified-files';
     151
    151152    const ITEM_TOOLS_TWO_FACTOR = 'tools-two-factor';
    152153    const ITEM_TOOLS_LIVE_TRAFFIC = 'tools-live-traffic';
     
    325326            case self::ITEM_SCAN_RESULT_UNKNOWN_FILE_CORE:
    326327            case self::ITEM_SCAN_RESULT_SKIPPED_PATHS:
    327                
     328            case self::ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES:
     329
    328330            case self::ITEM_TOOLS_TWO_FACTOR:
    329331            case self::ITEM_TOOLS_LIVE_TRAFFIC:
  • wordfence/trunk/lib/wfUpdateCheck.php

    r2131558 r2337484  
    1010    private $theme_updates = array();
    1111    private $api = null;
     12
     13    public static function syncAllVersionInfo() {
     14        // Load the core/plugin/theme versions into the WAF configuration.
     15        wfConfig::set('wordpressVersion', wfUtils::getWPVersion());
     16        wfWAFConfig::set('wordpressVersion', wfUtils::getWPVersion(), wfWAF::getInstance(), 'synced');
     17
     18        if (!function_exists('get_plugins')) {
     19            require_once(ABSPATH . '/wp-admin/includes/plugin.php');
     20        }
     21
     22        $pluginVersions = array();
     23        foreach (get_plugins() as $pluginFile => $pluginData) {
     24            $slug = plugin_basename($pluginFile);
     25            if (preg_match('/^([^\/]+)\//', $pluginFile, $matches)) {
     26                $slug = $matches[1];
     27            } else if (preg_match('/^([^\/.]+)\.php$/', $pluginFile, $matches)) {
     28                $slug = $matches[1];
     29            }
     30            $pluginVersions[$slug] = isset($pluginData['Version']) ? $pluginData['Version'] : null;
     31        }
     32
     33        wfConfig::set_ser('wordpressPluginVersions', $pluginVersions);
     34        wfWAFConfig::set('wordpressPluginVersions', $pluginVersions, wfWAF::getInstance(), 'synced');
     35
     36        if (!function_exists('wp_get_themes')) {
     37            require_once(ABSPATH . '/wp-includes/theme.php');
     38        }
     39
     40        $themeVersions = array();
     41        foreach (wp_get_themes() as $slug => $theme) {
     42            $themeVersions[$slug] = isset($theme['Version']) ? $theme['Version'] : null;
     43        }
     44
     45        wfConfig::set_ser('wordpressThemeVersions', $themeVersions);
     46        wfWAFConfig::set('wordpressThemeVersions', $themeVersions, wfWAF::getInstance(), 'synced');
     47    }
    1248
    1349    public function __construct() {
  • wordfence/trunk/lib/wfVersionCheckController.php

    r1879365 r2337484  
    66    const VERSION_UNSUPPORTED = 'unsupported';
    77   
    8     const PHP_DEPRECATING = '5.3.0'; //When greater than PHP_MINIMUM, will issue a discontinuing warning the first time we check it and find a version less than this (also applies to the other similar constant pairs)
    9     const PHP_MINIMUM = '5.2.0'; //The currently supported minimum
     8    const PHP_DEPRECATING = '5.5.0'; //When greater than PHP_MINIMUM, will issue a discontinuing warning the first time we check it and find a version less than this (also applies to the other similar constant pairs)
     9    const PHP_MINIMUM = '5.3.0'; //The currently supported minimum
    1010   
    1111    const OPENSSL_DEPRECATING = '1.0.1';
     
    4848                'phpVersionCheckDeprecationEmail_' . self::PHP_DEPRECATING,
    4949                __('PHP version too old', 'wordfence'),
    50                 sprintf(__('Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
     50                sprintf(__('Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
    5151            );
    5252           
     
    5454                'phpVersionCheckDeprecationNotice_' . self::PHP_DEPRECATING,
    5555                'phpVersionCheck',
    56                 sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
     56                sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that will no longer be supported by Wordfence in an upcoming release and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
    5757            );
    5858        }
     
    6161                'phpVersionCheckUnsupportedEmail_' . self::PHP_MINIMUM,
    6262                __('PHP version too old', 'wordfence'),
    63                 sprintf(__('Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
     63                sprintf(__('Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' ' . sprintf(__('Learn More: %s', 'wordfence'), wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP))
    6464            );
    6565           
     
    6767                'phpVersionCheckUnsupportedNotice_' . self::PHP_MINIMUM,
    6868                'phpVersionCheck',
    69                 sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP 7.x or 5.6 but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
     69                sprintf(__('<strong>WARNING: </strong> Your site is using a PHP version (%s) that is no longer supported by Wordfence and needs to be updated. We recommend using the newest version of PHP available but will currently support PHP versions as old as %s. Version checks are run regularly, so if you have successfully updated, you can dismiss this notice or check that the update has taken effect later.', 'wordfence'), phpversion(), self::PHP_DEPRECATING) . ' <a href="' . wfSupportController::esc_supportURL(wfSupportController::ITEM_VERSION_PHP) . '" target="_blank" rel="noopener noreferrer">' . __('Learn More', 'wordfence') . '</a>'
    7070            );
    7171        }
  • wordfence/trunk/lib/wordfenceClass.php

    r2325400 r2337484  
    317317            wfScanEngine::startScan(false, wfScanner::SCAN_TYPE_QUICK);
    318318        }
    319        
     319
     320        wfUpdateCheck::syncAllVersionInfo();
     321
    320322        wfConfig::remove('lastPermissionsTemplateCheck');
    321323    }
     
    12791281       
    12801282        add_action('upgrader_process_complete', 'wordfence::_refreshVulnerabilityCache');
     1283        add_action('upgrader_process_complete', 'wfUpdateCheck::syncAllVersionInfo');
    12811284        add_action('upgrader_process_complete', 'wordfence::_scheduleRefreshUpdateNotification', 99, 2);
    12821285        add_action('wordfence_refreshUpdateNotification', 'wordfence::_refreshUpdateNotification', 99, 0);
     
    22232226                    'betaThreatDefenseFeed' => !!wfConfig::get('betaThreatDefenseFeed'),
    22242227                    'disableWAFIPBlocking' => wfConfig::get('disableWAFIPBlocking'),
     2228                    'wordpressVersion' => wfConfig::get('wordpressVersion'),
     2229                    'wordpressPluginVersions' => wfConfig::get_ser('wordpressPluginVersions'),
     2230                    'wordpressThemeVersions' => wfConfig::get_ser('wordpressThemeVersions'),
    22252231                );
    22262232                if (wfUtils::isAdmin()) {
     
    25292535    public static function jsonAPIAuthorFilter($response, $handler, $request) {
    25302536        $route = $request->get_route();
    2531         if (!current_user_can('list_users')) {
     2537        if (!current_user_can('edit_others_posts')) {
    25322538            $urlBase = wfWP_REST_Users_Controller::wfGetURLBase();
    25332539            if (preg_match('~' . preg_quote($urlBase, '~') . '/*$~i', $route)) {
     
    34913497        return compact('result');
    34923498    }
     3499    public static function ajax_exportDiagnostics_callback(){
     3500        add_filter('gettext', 'wordfence::_diagnosticsTranslationDisabler', 0, 3);
     3501
     3502        $url = site_url();
     3503        $url = preg_replace('/^https?:\/\//i', '', $url);
     3504        $url = preg_replace('/[^a-zA-Z0-9\.]+/', '_', $url);
     3505        $url = preg_replace('/^_+/', '', $url);
     3506        $url = preg_replace('/_+$/', '', $url);
     3507
     3508        header('Content-Type: application/octet-stream');
     3509        header('Content-Disposition: attachment; filename="diagnostics_for_' . $url . '.txt"');
     3510
     3511        echo wfView::create('diagnostics/text', array(
     3512            'diagnostic' => new wfDiagnostic,
     3513            'plugins' => get_plugins(),
     3514        ));
     3515        exit;
     3516    }
    34933517    public static function _diagnosticsTranslationDisabler($translation, $text, $domain) {
    34943518        return $text;
     
    58045828            'switchTo2FANew', 'switchTo2FAOld',
    58055829            'wfcentral_step1', 'wfcentral_step2', 'wfcentral_step3', 'wfcentral_step4', 'wfcentral_step5', 'wfcentral_step6', 'wfcentral_disconnect',
     5830            'exportDiagnostics',
    58065831        ) as $func){
    58075832            add_action('wp_ajax_wordfence_' . $func, 'wordfence::ajaxReceiver');
     
    59045929            'modalHTMLTemplate' => wfView::create('common/modal-prompt', array('title' => '${title}', 'message' => '{{html message}}', 'primaryButton' => array('id' => 'wf-generic-modal-close', 'label' => __('Close', 'wordfence'), 'link' => '#')))->render(),
    59055930            'alertEmailBlacklist' => wfConfig::alertEmailBlacklist(),
     5931            'supportURLs' => array(
     5932                'scan-result-repair-modified-files' => esc_url_raw(wfSupportController::supportURL(wfSupportController::ITEM_SCAN_RESULT_REPAIR_MODIFIED_FILES)),
     5933            ),
    59065934            ));
    59075935    }
     
    75267554        $currentAutoPrependFile = ini_get('auto_prepend_file');
    75277555        $currentAutoPrepend = null;
    7528         if (isset($_POST['currentAutoPrepend']) && !WF_IS_WP_ENGINE) {
     7556        if (isset($_POST['currentAutoPrepend']) && !WF_IS_WP_ENGINE && !WF_IS_PRESSABLE) {
    75297557            $currentAutoPrepend = $_POST['currentAutoPrepend'];
    75307558        }
     
    76887716       
    76897717        try {
    7690             if ((!isset($_POST['iniModified']) || (isset($_POST['iniModified']) && !$_POST['iniModified']))) { //Uses .user.ini but not yet modified
     7718            if ((!isset($_POST['iniModified']) || (isset($_POST['iniModified']) && !$_POST['iniModified'])) && !WF_IS_PRESSABLE) { //Uses .user.ini but not yet modified
    76917719                $hasPreviousAutoPrepend = $helper->performIniRemoval($wp_filesystem);
    76927720               
     
    77297757            }
    77307758            else { //.user.ini and .htaccess modified if applicable and waiting period elapsed or otherwise ready to advance to next step
    7731                 if (WFWAF_AUTO_PREPEND && !WFWAF_SUBDIRECTORY_INSTALL && !WF_IS_WP_ENGINE) { //.user.ini modified, but the WAF is still enabled
     7759                if (WFWAF_AUTO_PREPEND && !WFWAF_SUBDIRECTORY_INSTALL && !WF_IS_WP_ENGINE && !WF_IS_PRESSABLE) { //.user.ini modified, but the WAF is still enabled
    77327760                    $retryAttempted = (isset($_POST['retryAttempted']) && $_POST['retryAttempted']);
    77337761                    $userIniError = '<p class="wf-error">';
     
    84898517
    84908518    public static function getWAFBootstrapPath() {
     8519        if (WF_IS_PRESSABLE) {
     8520            return WP_CONTENT_DIR . '/wordfence-waf.php';
     8521        }
    84918522        return ABSPATH . 'wordfence-waf.php';
    84928523    }
  • wordfence/trunk/modules/login-security/wordfence-login-security.php

    r2325400 r2337484  
    2828   
    2929    define('WORDFENCE_LS_VERSION', '1.0.5');
    30     define('WORDFENCE_LS_BUILD_NUMBER', '1592338782');
     30    define('WORDFENCE_LS_BUILD_NUMBER', '1594219913');
    3131   
    3232    if (!defined('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES')) { define('WORDFENCE_LS_EMAIL_VALIDITY_DURATION_MINUTES', 15); }
  • wordfence/trunk/readme.txt

    r2325413 r2337484  
    184184== Changelog ==
    185185
     186= 7.4.9 - July 8, 2020 =
     187
     188* Improvement: Added list of known malicious usernames to suspicious administrator scan.
     189* Improvement: Added ability for the WAF to determine if a given plugin/theme/core version is installed.
     190* Improvement: Added a feature to export a diagnostics report.
     191* Improvement: Add php_errorlog to the list of downloadable logs in diagnostics.
     192* Improvement: Added a prompt to allow user to download a backup prior to repairing files.
     193* Improvement: Prevent scan from failing when the home URL has changed and the key is no longer valid.
     194* Improvement: Deprecated PHP 5.3, and ended PHP 5.2 support by prevent auto-update from running on older versions.
     195* Fix: Fixed issue where WAF mysqli storage engine cannot find credentials if wflogs/ does not exist.
     196* Fix: Changed capability checked to read WP REST API users endpoint when "Prevent discovery of usernames through ..." is enabled.
     197* Fix: Prevented duplicate queries for wordfenceCentralConnected wfconfig value.
     198* Fix: Prevented custom wp-content or other directories from appearing in "skipped paths" scan result, even when scanned.
     199* Fix: Login Attempts dashboard widget "Show more" link is not visible when long usernames and IPs cause wrapping.
     200* Fix: Fix typo in the readme.
     201
    186202= 7.4.8 - June 16, 2020 =
    187203* Fix: Fixed issue with fatal errors encountered during activation under certain conditions.
     
    194210* Improvement: Added the state/province name when applicable to geolocation displays in Live Traffic.
    195211* Improvement: New blocking page design to better inform blocked visitors on how to resolve the block.
    196 * Improvement: Custom WP_CONTENT_DIR, WP_PLUGIN_DUR, and UPLOADS path constants will now get scanned correctly.
     212* Improvement: Custom WP_CONTENT_DIR, WP_PLUGIN_DIR, and UPLOADS path constants will now get scanned correctly.
    197213* Improvement: Added TLS connection failure detection to brute force reporting and checking and a corresponding backoff period.
    198214* Fix: Fixed an issue where a bad cron record could interfere with automatic WAF rule updates.
  • wordfence/trunk/vendor/wordfence/wf-waf/src/init.php

    r2143823 r2337484  
    66define('WFWAF_LIB_PATH', WFWAF_PATH . 'lib/');
    77define('WFWAF_VIEW_PATH', WFWAF_PATH . 'views/');
    8 define('WFWAF_API_URL_SEC', 'https://noc4.wordfence.com/v1.8/');
     8define('WFWAF_API_URL_SEC', 'https://noc4.wordfence.com/v1.9/');
    99if (!defined('WFWAF_DEBUG')) {
    1010    define('WFWAF_DEBUG', false);
  • wordfence/trunk/vendor/wordfence/wf-waf/src/lib/rules.php

    r2226721 r2337484  
    497497        'urlschemematches',
    498498        'urlschemenotmatches',
     499        'versionequals',
     500        'versionnotequals',
     501        'versiongreaterthan',
     502        'versiongreaterthanequalto',
     503        'versionlessthan',
     504        'versionlessthanequalto',
    499505    );
    500506
     
    11321138    }
    11331139
     1140    public function versionEquals($subject) {
     1141        if ($subject === null) {
     1142            return false;
     1143        }
     1144        return version_compare($subject, $this->getExpected(), '==');
     1145    }
     1146
     1147    public function versionNotEquals($subject) {
     1148        if ($subject === null) {
     1149            return false;
     1150        }
     1151        return version_compare($subject, $this->getExpected(), '!=');
     1152    }
     1153
     1154    public function versionGreaterThan($subject) {
     1155        if ($subject === null) {
     1156            return false;
     1157        }
     1158        return version_compare($subject, $this->getExpected(), '>');
     1159    }
     1160
     1161    public function versionGreaterThanEqualTo($subject) {
     1162        if ($subject === null) {
     1163            return false;
     1164        }
     1165        return version_compare($subject, $this->getExpected(), '>=');
     1166    }
     1167
     1168    public function versionLessThan($subject) {
     1169        if ($subject === null) {
     1170            return false;
     1171        }
     1172        return version_compare($subject, $this->getExpected(), '<');
     1173    }
     1174
     1175    public function versionLessThanEqualTo($subject) {
     1176        if ($subject === null) {
     1177            return false;
     1178        }
     1179        return version_compare($subject, $this->getExpected(), '<=');
     1180    }
     1181
    11341182    /**
    11351183     * @return mixed
  • wordfence/trunk/views/scanner/issue-control-repair.php

    r1808795 r2337484  
    22if (!defined('WORDFENCE_VERSION')) { exit; }
    33?>
    4 {{if data.canFix}}<a href="#" class="wf-issue-control wf-issue-control-repair"><svg class="wf-issue-control-icon" viewBox="0 0 106.7 106.7"><path d="M104.94,18.77a4,4,0,0,0-1.17-2.93L90.86,2.93a4.25,4.25,0,0,0-5.87,0L1.17,86.75a4.25,4.25,0,0,0,0,5.86l12.91,12.91A4,4,0,0,0,17,106.7a4,4,0,0,0,2.93-1.17L103.77,21.7a4,4,0,0,0,1.17-2.93ZM75.8,37.87l-7-7,19.1-19.1,7,7Zm0,0"/><path d="M14.93,16.68l2-6.39,6.39-2-6.39-2L14.93,0,13,6.39l-6.39,2,6.39,2Zm0,0"/><path d="M31.87,24.77l3.91,12.77L39.7,24.77l12.77-3.91L39.7,16.95,35.78,4.17,31.87,16.95,19.1,20.86Zm0,0"/><path d="M100.31,48.1l-2-6.39-2,6.39-6.39,2,6.39,2,2,6.39,2-6.39,6.39-2Zm0,0"/><path d="M56.64,16.68l2-6.39,6.39-2-6.39-2L56.64,0l-2,6.39-6.39,2,6.39,2Zm0,0"/></svg><span class="wf-issue-control-label"><?php _e('Repair', 'wordfence'); ?></span></a>{{/if}}
     4{{if data.canFix}}<a href="#" class="wf-issue-control wf-issue-control-repair" data-file="${data.file}"><svg class="wf-issue-control-icon" viewBox="0 0 106.7 106.7"><path d="M104.94,18.77a4,4,0,0,0-1.17-2.93L90.86,2.93a4.25,4.25,0,0,0-5.87,0L1.17,86.75a4.25,4.25,0,0,0,0,5.86l12.91,12.91A4,4,0,0,0,17,106.7a4,4,0,0,0,2.93-1.17L103.77,21.7a4,4,0,0,0,1.17-2.93ZM75.8,37.87l-7-7,19.1-19.1,7,7Zm0,0"/><path d="M14.93,16.68l2-6.39,6.39-2-6.39-2L14.93,0,13,6.39l-6.39,2,6.39,2Zm0,0"/><path d="M31.87,24.77l3.91,12.77L39.7,24.77l12.77-3.91L39.7,16.95,35.78,4.17,31.87,16.95,19.1,20.86Zm0,0"/><path d="M100.31,48.1l-2-6.39-2,6.39-6.39,2,6.39,2,2,6.39,2-6.39,6.39-2Zm0,0"/><path d="M56.64,16.68l2-6.39,6.39-2-6.39-2L56.64,0l-2,6.39-6.39,2,6.39,2Zm0,0"/></svg><span class="wf-issue-control-label"><?php _e('Repair', 'wordfence'); ?></span></a>{{/if}}
  • wordfence/trunk/views/scanner/options-group-general.php

    r2187129 r2337484  
    4747                        array('key' => 'scansEnabled_suspiciousOptions', 'label' => __('Scan WordPress core, plugin, and theme options for known dangerous URLs and suspicious content', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_MALWARE_OPTIONS)),
    4848                        array('key' => 'scansEnabled_oldVersions', 'label' => __('Scan for out of date, abandoned, and vulnerable plugins, themes, and WordPress versions', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_UPDATES)),
    49                         array('key' => 'scansEnabled_suspiciousAdminUsers', 'label' => __('Scan for admin users created outside of WordPress', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_UNKNOWN_ADMINS)),
     49                        array('key' => 'scansEnabled_suspiciousAdminUsers', 'label' => __('Scan for suspicious admin users created outside of WordPress', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_UNKNOWN_ADMINS)),
    5050                        array('key' => 'scansEnabled_passwds', 'label' => __('Check the strength of passwords', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_PASSWORD_STRENGTH)),
    5151                        array('key' => 'scansEnabled_diskSpace', 'label' => __('Monitor disk space', 'wordfence'), 'helpLink' => wfSupportController::supportURL(wfSupportController::ITEM_SCAN_OPTION_DISK_SPACE)),
  • wordfence/trunk/views/waf/waf-install.php

    r2143823 r2337484  
    1818            <?php
    1919            $currentAutoPrependFile = ini_get('auto_prepend_file');
    20             if (empty($currentAutoPrependFile) || WF_IS_WP_ENGINE):
     20            if (empty($currentAutoPrependFile) || WF_IS_WP_ENGINE || WF_IS_PRESSABLE):
    2121            ?>
    2222            <p><?php _e('To make your site as secure as possible, the Wordfence Web Application Firewall is designed to run via a PHP setting called <code>auto_prepend_file</code>, which ensures it runs before any potentially vulnerable code runs.', 'wordfence'); ?></p>
  • wordfence/trunk/views/waf/waf-uninstall.php

    r2143823 r2337484  
    1717        <div class="wf-modal-content">
    1818        <?php
    19         if (WF_IS_WP_ENGINE) {
     19        if (WF_IS_WP_ENGINE || WF_IS_PRESSABLE) {
    2020            $currentAutoPrependFile = wordfence::getWAFBootstrapPath();
    2121        } else {
  • wordfence/trunk/waf/bootstrap.php

    r2290265 r2337484  
    1212if (!defined('WF_IS_WP_ENGINE')) {
    1313    define('WF_IS_WP_ENGINE', isset($_SERVER['IS_WPE']));
     14}
     15if (!defined('WF_IS_PRESSABLE')) {
     16    define('WF_IS_PRESSABLE', (defined('IS_ATOMIC') && IS_ATOMIC) || (defined('IS_PRESSABLE') && IS_PRESSABLE));
    1417}
    1518
     
    693696        @chmod(rtrim(WFWAF_LOG_PATH, '/') . '/.htaccess', (wfWAFWordPress::permissions() | 0444));
    694697    }
     698
     699    public function getGlobal($global) {
     700        if (wfWAFUtils::strpos($global, '.') === false) {
     701            return null;
     702        }
     703        list($prefix, $_global) = explode('.', $global);
     704        switch ($prefix) {
     705            case 'wordpress':
     706                if ($_global === 'core') {
     707                    return $this->getStorageEngine()->getConfig('wordpressVersion', null, 'synced');
     708                } else if ($_global === 'plugins') {
     709                    return $this->getStorageEngine()->getConfig('wordpressPluginVersions', null, 'synced');
     710                } else if ($_global === 'themes') {
     711                    return $this->getStorageEngine()->getConfig('wordpressThemeVersions', null, 'synced');
     712                }
     713                break;
     714        }
     715        return parent::getGlobal($global);
     716    }
     717}
     718
     719class wfWAFWordPressStorageMySQL extends wfWAFStorageMySQL {
     720
     721    public function getSerializedParams() {
     722        $params = parent::getSerializedParams();
     723        $params[] = 'wordpressPluginVersions';
     724        $params[] = 'wordpressThemeVersions';
     725        return $params;
     726    }
     727
     728    public function getAutoloadParams() {
     729        $params = parent::getAutoloadParams();
     730        $params['synced'][] = 'wordpressVersion';
     731        $params['synced'][] = 'wordpressPluginVersions';
     732        $params['synced'][] = 'wordpressThemeVersions';
     733        return $params;
     734    }
    695735}
    696736
     
    718758            case 'mysqli':
    719759                // Find the wp-config.php
    720                 if (file_exists(dirname(WFWAF_LOG_PATH) . '/../wp-config.php')) {
    721                     $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(WFWAF_LOG_PATH . '/../../wp-config.php');
    722                 } else if (file_exists(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php')) {
    723                     $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(WFWAF_LOG_PATH . '/../../../wp-config.php');
     760                if (is_dir(dirname(WFWAF_LOG_PATH))) {
     761                    if (file_exists(dirname(WFWAF_LOG_PATH) . '/../wp-config.php')) {
     762                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(dirname(WFWAF_LOG_PATH) . '/../wp-config.php');
     763                    } else if (file_exists(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php')) {
     764                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig(dirname(WFWAF_LOG_PATH) . '/../../wp-config.php');
     765                    }
     766                } else if (!empty($_SERVER['DOCUMENT_ROOT'])) {
     767                    if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php')) {
     768                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig($_SERVER['DOCUMENT_ROOT'] . '/wp-config.php');
     769                    } else if (file_exists($_SERVER['DOCUMENT_ROOT'] . '/../wp-config.php')) {
     770                        $wfWAFDBCredentials = wfWAFUtils::extractCredentialsWPConfig($_SERVER['DOCUMENT_ROOT'] . '/../wp-config.php');
     771                    }
    724772                }
    725773
    726774                if (!empty($wfWAFDBCredentials)) {
    727                     $wfWAFStorageEngine = new wfWAFStorageMySQL(new wfWAFStorageEngineMySQLi(), $wfWAFDBCredentials['tablePrefix']);
     775                    $wfWAFStorageEngine = new wfWAFWordPressStorageMySQL(new wfWAFStorageEngineMySQLi(), $wfWAFDBCredentials['tablePrefix']);
    728776                    $wfWAFStorageEngine->getDb()->connect(
    729777                        $wfWAFDBCredentials['user'],
  • wordfence/trunk/wordfence.php

    r2325400 r2337484  
    55Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
    66Author: Wordfence
    7 Version: 7.4.8
     7Version: 7.4.9
    88Author URI: http://www.wordfence.com/
    99Network: true
     
    1616    exit;
    1717}
    18 define('WORDFENCE_VERSION', '7.4.8');
    19 define('WORDFENCE_BUILD_NUMBER', '1592338782');
     18define('WORDFENCE_VERSION', '7.4.9');
     19define('WORDFENCE_BUILD_NUMBER', '1594219913');
    2020define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
    2121    basename(dirname(__FILE__)) . '/' . basename(__FILE__));
     
    3737if (!defined('WF_IS_WP_ENGINE')) {
    3838    define('WF_IS_WP_ENGINE', isset($_SERVER['IS_WPE']));
     39}
     40if (!defined('WF_IS_PRESSABLE')) {
     41    define('WF_IS_PRESSABLE', (defined('IS_ATOMIC') && IS_ATOMIC) || (defined('IS_PRESSABLE') && IS_PRESSABLE));
    3942}
    4043
Note: See TracChangeset for help on using the changeset viewer.