Plugin Directory

Changeset 2107617


Ignore:
Timestamp:
06/17/2019 07:05:45 PM (7 years ago)
Author:
wfmatt
Message:
  • Improvement: Added security events and alerting features built into Wordfence Central.
Location:
wordfence
Files:
114 added
116 deleted
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • wordfence/tags/7.3.4/lib/wfCentralAPI.php

    r2104182 r2107617  
    4848            $args['headers'] = array();
    4949        }
    50         $args['cookies']['XDEBUG_SESSION'] = 'XDEBUG_ECLIPSE';
    5150
    5251        $token = $this->getToken();
     
    502501        return false;
    503502    }
     503
     504    /**
     505     * @param string $event
     506     * @param array $data
     507     * @param callable|null $alertCallback
     508     */
     509    public static function sendSecurityEvent($event, $data = array(), $alertCallback = null) {
     510        $alerted = false;
     511        if (!self::pluginAlertingDisabled() && is_callable($alertCallback)) {
     512            call_user_func($alertCallback);
     513            $alerted = true;
     514        }
     515
     516        $siteID = wfConfig::get('wordfenceCentralSiteID');
     517        $request = new wfCentralAuthenticatedAPIRequest('/site/' . $siteID . '/security-events', 'POST', array(
     518            'data' => array(
     519                array(
     520                    'type'       => 'security-event',
     521                    'attributes' => array(
     522                        'type'       => $event,
     523                        'data'       => $data,
     524                        'event_time' => microtime(true),
     525                    ),
     526                ),
     527            ),
     528        ));
     529        try {
     530            // Attempt to send the security event to Central.
     531            $response = $request->execute();
     532        } catch (wfCentralAPIException $e) {
     533            // If we didn't alert previously, notify the user now in the event Central is down.
     534            if (!$alerted && is_callable($alertCallback)) {
     535                call_user_func($alertCallback);
     536            }
     537        }
     538    }
     539
     540    /**
     541     * @param $event
     542     * @param array $data
     543     * @param callable|null $alertCallback
     544     */
     545    public static function sendAlertCallback($event, $data = array(), $alertCallback = null) {
     546        if (is_callable($alertCallback)) {
     547            call_user_func($alertCallback);
     548        }
     549    }
     550
     551    public static function pluginAlertingDisabled() {
     552        if (!self::isConnected()) {
     553            return false;
     554        }
     555
     556        return wfConfig::get('wordfenceCentralPluginAlertingDisabled', false);
     557    }
    504558}
  • wordfence/tags/7.3.4/lib/wfConfig.php

    r2087795 r2107617  
    232232        'wordfenceCentralUserSiteAuthGrant',
    233233        'wordfenceCentralConnected',
     234        'wordfenceCentralPluginAlertingDisabled',
    234235    );
    235236
     
    990991            if($upret){
    991992                $cont = file_get_contents(WORDFENCE_FCPATH);
    992                 if(wfConfig::get('alertOn_update') == '1' && preg_match('/Version: (\d+\.\d+\.\d+)/', $cont, $matches) ){
    993                     wordfence::alert("Wordfence Upgraded to version " . $matches[1], "Your Wordfence installation has been upgraded to version " . $matches[1], '127.0.0.1');
    994                 }
     993                preg_match('/Version: (\d+\.\d+\.\d+)/', $cont, $matches);
     994                $version = !empty($matches) ? $matches[1] : null;
     995                $alertCallback = array(new wfAutoUpdatedAlert($version), 'send');
     996                do_action('wordfence_security_event', 'autoUpdate', array(
     997                    'version' => $version,
     998                    'ip' => wfUtils::getIP(),
     999                ), $alertCallback);
     1000
    9951001                wfConfig::set('autoUpdateAttempts', 0);
    9961002            }
     
    13291335                   
    13301336                    if ($value == wfFirewall::FIREWALL_MODE_DISABLED) {
    1331                         if (wfConfig::get('alertOn_wafDeactivated')) {
    1332                             $currentUser = wp_get_current_user();
    1333                             $username = $currentUser->user_login;
    1334                             wordfence::alert(__('Wordfence WAF Deactivated', 'wordfence'), sprintf(__('A user with username "%s" deactivated the Wordfence Web Application Firewall on your WordPress site.', 'wordfence'), $username), wfUtils::getIP());
    1335                         }
     1337                        $currentUser = wp_get_current_user();
     1338                        $username = $currentUser->user_login;
     1339
     1340                        $alertCallback = array(new wfWafDeactivatedAlert($username, wfUtils::getIP()), 'send');
     1341                        do_action('wordfence_security_event', 'wafDeactivated', array(
     1342                            'username' => $username,
     1343                            'ip' => wfUtils::getIP(),
     1344                        ), $alertCallback);
    13361345                    }
    13371346                   
  • wordfence/tags/7.3.4/lib/wfLog.php

    r2087795 r2107617  
    633633                wfActivityReport::logBlockedIP($IP, null, 'throttle');
    634634                $this->tagRequestForBlock($reason);
    635                
    636                 if (wfConfig::get('alertOn_block')) {
    637                     $message = sprintf(__('Wordfence has blocked IP address %s.', 'wordfence'), $IP) . "\n";
    638                     $message .= sprintf(__('The reason is: "%s".', 'wordfence'), $reason);
    639                     if ($secsToGo > 0) {
    640                         $message .= "\n" . sprintf(__('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($secsToGo, true));
    641                     }
    642                     wordfence::alert(sprintf(__('Blocking IP %s', 'wordfence'), $IP), $message, $IP);
    643                 }
     635
     636                $alertCallback = array(new wfBlockAlert($IP, $reason, $secsToGo), 'send');
     637
     638                do_action('wordfence_security_event', 'block', array(
     639                    'ip' => $IP,
     640                    'reason' => $reason,
     641                    'duration' => $secsToGo,
     642                ), $alertCallback);
    644643                wordfence::status(2, 'info', sprintf(__('Blocking IP %s. %s', 'wordfence'), $IP, $reason));
    645644            }
     
    648647                wfBlock::createRateThrottle($reason, $IP, $secsToGo);
    649648                wfActivityReport::logBlockedIP($IP, null, 'throttle');
    650                
     649
     650                do_action('wordfence_security_event', 'throttle', array(
     651                    'ip' => $IP,
     652                    'reason' => $reason,
     653                    'duration' => $secsToGo,
     654                ));
    651655                wordfence::status(2, 'info', sprintf(__('Throttling IP %s. %s', 'wordfence'), $IP, $reason));
    652656                wfConfig::inc('totalIPsThrottled');
    653657            }
    654             $this->do503($secsToGo, $reason);
     658            $this->do503($secsToGo, $reason, false);
    655659        }
    656660       
     
    670674    }
    671675   
    672     public function do503($secsToGo, $reason){
     676    public function do503($secsToGo, $reason, $sendEventToCentral = true){
    673677        $this->initLogRequest();
     678
     679        if ($sendEventToCentral) {
     680            do_action('wordfence_security_event', 'block', array(
     681                'ip' => wfUtils::inet_ntop($this->currentRequest->IP),
     682                'reason' => $this->currentRequest->actionDescription ? $this->currentRequest->actionDescription : $reason,
     683                'duration' => $secsToGo,
     684            ));
     685        }
     686
    674687        $this->currentRequest->statusCode = 503;
    675688        if (!$this->currentRequest->action) {
  • wordfence/tags/7.3.4/lib/wordfenceClass.php

    r2104182 r2107617  
    4242require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
    4343require_once(dirname(__FILE__) . '/wfModuleController.php');
     44require_once(dirname(__FILE__) . '/wfAlerts.php');
    4445
    4546if (version_compare(phpversion(), '5.3', '>=')) {
     
    9697    public static function uninstallPlugin(){
    9798        //Send admin alert
    98         if (wfConfig::get('alertOn_wordfenceDeactivated')) {
    99             $currentUser = wp_get_current_user();
    100             $username = $currentUser->user_login;
    101             wordfence::alert("Wordfence Deactivated", "A user with username \"$username\" deactivated Wordfence on your WordPress site.", wfUtils::getIP());
    102         }
     99        $currentUser = wp_get_current_user();
     100        $username = $currentUser->user_login;
     101        $alertCallback = array(new wfWordfenceDeactivatedAlert($username, wfUtils::getIP()), 'send');
     102        do_action('wordfence_security_event', 'wordfenceDeactivated', array(
     103            'username' => $username,
     104            'ip' => wfUtils::getIP(),
     105        ), $alertCallback);
    103106       
    104107        //Check if caching is enabled and if it is, disable it and fix the .htaccess file.
     
    13111314        add_action('rest_api_init', 'wordfence::initRestAPI');
    13121315
     1316        if (wfCentral::isConnected()) {
     1317            add_action('wordfence_security_event', 'wfCentral::sendSecurityEvent', 10, 3);
     1318        } else {
     1319            add_action('wordfence_security_event', 'wfCentral::sendAlertCallback', 10, 3);
     1320        }
    13131321    }
    13141322    public static function _pluginPageActionLinks($links) {
     
    16651673
    16661674        if($user){
    1667             if(wfConfig::get('alertOn_lostPasswdForm')){
    1668                 wordfence::alert("Password recovery attempted", "Someone tried to recover the password for user with email address: " . wp_kses($user->user_email, array()), $IP);
    1669             }
     1675            $alertCallback = array(new wfLostPasswdFormAlert($user, wfUtils::getIP()), 'send');
     1676            do_action('wordfence_security_event', 'lostPasswdForm', array(
     1677                'email' => $user->user_email,
     1678                'ip' => wfUtils::getIP(),
     1679            ), $alertCallback);
     1680
    16701681        }
    16711682        if(wfConfig::get('loginSecurityEnabled')){
     
    16881699        wfBlock::createLockout($reason, $IP, wfBlock::lockoutDuration(), time(), time(), 1);
    16891700        self::getLog()->tagRequestForLockout($reason);
    1690         if (wfConfig::get('alertOn_loginLockout')) {
    1691             $message = sprintf(__('A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s.', 'wordfence'), $IP, $reason);
    1692             if (wfBlock::lockoutDuration() > 0) {
    1693                 $message .= "\n" . sprintf(__('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
    1694             }
    1695             wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $IP);
    1696         }
     1701        $alertCallback = array(new wfLoginLockoutAlert($IP, $reason), 'send');
     1702        do_action('wordfence_security_event', 'loginLockout', array(
     1703            'ip'       => $IP,
     1704            'reason'   => $reason,
     1705            'duration' => wfBlock::lockoutDuration(),
     1706        ), $alertCallback);
     1707
    16971708    }
    16981709
     
    24032414        $cookievalue = hash_hmac('sha256', $user->user_login, $salt);
    24042415        if(wfUtils::isAdmin($userID)){
    2405             if(wfConfig::get('alertOn_adminLogin')){
    2406                 $shouldAlert = true;
    2407                 if (wfConfig::get('alertOn_firstAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
    2408                     $shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
    2409                 }
    2410                
    2411                 if ($shouldAlert) {
    2412                     wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
    2413                 }
    2414             }
     2416            $securityEvent = 'adminLoginNewLocation';
     2417            if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
     2418                $securityEvent = 'adminLogin';
     2419            }
     2420            $alertCallback = array(new wfAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
     2421            do_action('wordfence_security_event', $securityEvent, array(
     2422                'username' => $username,
     2423                'ip' => wfUtils::getIP(),
     2424            ), $alertCallback);
     2425
    24152426        } else {
    2416             if(wfConfig::get('alertOn_nonAdminLogin')){
    2417                 $shouldAlert = true;
    2418                 if (wfConfig::get('alertOn_firstNonAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
    2419                     $shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
    2420                 }
    2421                
    2422                 if ($shouldAlert) {
    2423                     wordfence::alert("User login", "A non-admin user with username \"$username\" signed in to your WordPress site.", wfUtils::getIP());
    2424                 }
    2425             }
     2427            $securityEvent = 'nonAdminLoginNewLocation';
     2428            if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
     2429                $securityEvent = 'nonAdminLogin';
     2430            }
     2431            $alertCallback = array(new wfNonAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
     2432            do_action('wordfence_security_event', $securityEvent, array(
     2433                'username' => $username,
     2434                'ip' => wfUtils::getIP(),
     2435            ), $alertCallback);
    24262436        }
    24272437       
     
    29232933                        $username = $authUser->user_login;
    29242934                        self::getLog()->logLogin('loginFailValidUsername', 1, $username);
    2925                         if (wfConfig::get('alertOn_breachLogin')) {
    2926                             wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), wfUtils::getIP());
    2927                         }
     2935                        $alertCallback = array(new wfBreachLoginAlert($username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD), wfUtils::getIP()), 'send');
     2936
     2937                        do_action('wordfence_security_event', 'breachLogin', array(
     2938                            'username' => $username,
     2939                            'resetPasswordURL' => wp_lostpassword_url(),
     2940                            'supportURL' => wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD),
     2941                            'ip' => wfUtils::getIP(),
     2942                        ), $alertCallback);
    29282943                       
    29292944                        remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
     
    29522967                $username = $authUser->user_login;
    29532968                self::getLog()->logLogin('loginFailValidUsername', 1, $username);
    2954                 if (wfConfig::get('alertOn_breachLogin')) {
    2955                     wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), wfUtils::getIP());
    2956                 }
    2957                
     2969                $alertCallback = array(new wfBreachLoginAlert($username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD), wfUtils::getIP()), 'send');
     2970
     2971                do_action('wordfence_security_event', 'breachLogin', array(
     2972                    'username' => $username,
     2973                    'resetPasswordURL' => wp_lostpassword_url(),
     2974                    'supportURL' => wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD),
     2975                    'ip' => wfUtils::getIP(),
     2976                ), $alertCallback);
     2977
    29582978                remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
    29592979                self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
     
    78767896                }
    78777897
    7878                 self::alert('Increased Attack Rate', $message, false);
     7898                $alertCallback = array(new wfIncreasedAttackRateAlert($message), 'send');
     7899                do_action('wordfence_security_event', 'increasedAttackRate', array(
     7900                    'attackCount' => $attackCount,
     7901                    'attackTable' => $attackTable,
     7902                    'duration' => $alertInterval,
     7903                    'ip' => wfUtils::getIP(),
     7904                ), $alertCallback);
     7905
    78797906                wfConfig::set('wafAlertLastSendTime', time());
    78807907            }
  • wordfence/tags/7.3.4/modules/login-security/wordfence-login-security.php

    r2104182 r2107617  
    2828   
    2929    define('WORDFENCE_LS_VERSION', '1.0.2');
    30     define('WORDFENCE_LS_BUILD_NUMBER', '1560275180');
     30    define('WORDFENCE_LS_BUILD_NUMBER', '1560795818');
    3131   
    3232    if (!WORDFENCE_LS_FROM_CORE) {
  • wordfence/tags/7.3.4/readme.txt

    r2104194 r2107617  
    183183
    184184== Changelog ==
     185
     186= 7.3.4 - June 17, 2019 =
     187* Improvement: Added security events and alerting features built into Wordfence Central.
    185188
    186189= 7.3.3 - June 11, 2019 =
  • wordfence/tags/7.3.4/wordfence.php

    r2104182 r2107617  
    55Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
    66Author: Wordfence
    7 Version: 7.3.3
     7Version: 7.3.4
    88Author URI: http://www.wordfence.com/
    99Network: true
     
    1616    exit;
    1717}
    18 define('WORDFENCE_VERSION', '7.3.3');
    19 define('WORDFENCE_BUILD_NUMBER', '1560275180');
     18define('WORDFENCE_VERSION', '7.3.4');
     19define('WORDFENCE_BUILD_NUMBER', '1560795818');
    2020define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
    2121    basename(dirname(__FILE__)) . '/' . basename(__FILE__));
  • wordfence/trunk/lib/wfCentralAPI.php

    r2104182 r2107617  
    4848            $args['headers'] = array();
    4949        }
    50         $args['cookies']['XDEBUG_SESSION'] = 'XDEBUG_ECLIPSE';
    5150
    5251        $token = $this->getToken();
     
    502501        return false;
    503502    }
     503
     504    /**
     505     * @param string $event
     506     * @param array $data
     507     * @param callable|null $alertCallback
     508     */
     509    public static function sendSecurityEvent($event, $data = array(), $alertCallback = null) {
     510        $alerted = false;
     511        if (!self::pluginAlertingDisabled() && is_callable($alertCallback)) {
     512            call_user_func($alertCallback);
     513            $alerted = true;
     514        }
     515
     516        $siteID = wfConfig::get('wordfenceCentralSiteID');
     517        $request = new wfCentralAuthenticatedAPIRequest('/site/' . $siteID . '/security-events', 'POST', array(
     518            'data' => array(
     519                array(
     520                    'type'       => 'security-event',
     521                    'attributes' => array(
     522                        'type'       => $event,
     523                        'data'       => $data,
     524                        'event_time' => microtime(true),
     525                    ),
     526                ),
     527            ),
     528        ));
     529        try {
     530            // Attempt to send the security event to Central.
     531            $response = $request->execute();
     532        } catch (wfCentralAPIException $e) {
     533            // If we didn't alert previously, notify the user now in the event Central is down.
     534            if (!$alerted && is_callable($alertCallback)) {
     535                call_user_func($alertCallback);
     536            }
     537        }
     538    }
     539
     540    /**
     541     * @param $event
     542     * @param array $data
     543     * @param callable|null $alertCallback
     544     */
     545    public static function sendAlertCallback($event, $data = array(), $alertCallback = null) {
     546        if (is_callable($alertCallback)) {
     547            call_user_func($alertCallback);
     548        }
     549    }
     550
     551    public static function pluginAlertingDisabled() {
     552        if (!self::isConnected()) {
     553            return false;
     554        }
     555
     556        return wfConfig::get('wordfenceCentralPluginAlertingDisabled', false);
     557    }
    504558}
  • wordfence/trunk/lib/wfConfig.php

    r2087795 r2107617  
    232232        'wordfenceCentralUserSiteAuthGrant',
    233233        'wordfenceCentralConnected',
     234        'wordfenceCentralPluginAlertingDisabled',
    234235    );
    235236
     
    990991            if($upret){
    991992                $cont = file_get_contents(WORDFENCE_FCPATH);
    992                 if(wfConfig::get('alertOn_update') == '1' && preg_match('/Version: (\d+\.\d+\.\d+)/', $cont, $matches) ){
    993                     wordfence::alert("Wordfence Upgraded to version " . $matches[1], "Your Wordfence installation has been upgraded to version " . $matches[1], '127.0.0.1');
    994                 }
     993                preg_match('/Version: (\d+\.\d+\.\d+)/', $cont, $matches);
     994                $version = !empty($matches) ? $matches[1] : null;
     995                $alertCallback = array(new wfAutoUpdatedAlert($version), 'send');
     996                do_action('wordfence_security_event', 'autoUpdate', array(
     997                    'version' => $version,
     998                    'ip' => wfUtils::getIP(),
     999                ), $alertCallback);
     1000
    9951001                wfConfig::set('autoUpdateAttempts', 0);
    9961002            }
     
    13291335                   
    13301336                    if ($value == wfFirewall::FIREWALL_MODE_DISABLED) {
    1331                         if (wfConfig::get('alertOn_wafDeactivated')) {
    1332                             $currentUser = wp_get_current_user();
    1333                             $username = $currentUser->user_login;
    1334                             wordfence::alert(__('Wordfence WAF Deactivated', 'wordfence'), sprintf(__('A user with username "%s" deactivated the Wordfence Web Application Firewall on your WordPress site.', 'wordfence'), $username), wfUtils::getIP());
    1335                         }
     1337                        $currentUser = wp_get_current_user();
     1338                        $username = $currentUser->user_login;
     1339
     1340                        $alertCallback = array(new wfWafDeactivatedAlert($username, wfUtils::getIP()), 'send');
     1341                        do_action('wordfence_security_event', 'wafDeactivated', array(
     1342                            'username' => $username,
     1343                            'ip' => wfUtils::getIP(),
     1344                        ), $alertCallback);
    13361345                    }
    13371346                   
  • wordfence/trunk/lib/wfLog.php

    r2087795 r2107617  
    633633                wfActivityReport::logBlockedIP($IP, null, 'throttle');
    634634                $this->tagRequestForBlock($reason);
    635                
    636                 if (wfConfig::get('alertOn_block')) {
    637                     $message = sprintf(__('Wordfence has blocked IP address %s.', 'wordfence'), $IP) . "\n";
    638                     $message .= sprintf(__('The reason is: "%s".', 'wordfence'), $reason);
    639                     if ($secsToGo > 0) {
    640                         $message .= "\n" . sprintf(__('The duration of the block is %s.', 'wordfence'), wfUtils::makeDuration($secsToGo, true));
    641                     }
    642                     wordfence::alert(sprintf(__('Blocking IP %s', 'wordfence'), $IP), $message, $IP);
    643                 }
     635
     636                $alertCallback = array(new wfBlockAlert($IP, $reason, $secsToGo), 'send');
     637
     638                do_action('wordfence_security_event', 'block', array(
     639                    'ip' => $IP,
     640                    'reason' => $reason,
     641                    'duration' => $secsToGo,
     642                ), $alertCallback);
    644643                wordfence::status(2, 'info', sprintf(__('Blocking IP %s. %s', 'wordfence'), $IP, $reason));
    645644            }
     
    648647                wfBlock::createRateThrottle($reason, $IP, $secsToGo);
    649648                wfActivityReport::logBlockedIP($IP, null, 'throttle');
    650                
     649
     650                do_action('wordfence_security_event', 'throttle', array(
     651                    'ip' => $IP,
     652                    'reason' => $reason,
     653                    'duration' => $secsToGo,
     654                ));
    651655                wordfence::status(2, 'info', sprintf(__('Throttling IP %s. %s', 'wordfence'), $IP, $reason));
    652656                wfConfig::inc('totalIPsThrottled');
    653657            }
    654             $this->do503($secsToGo, $reason);
     658            $this->do503($secsToGo, $reason, false);
    655659        }
    656660       
     
    670674    }
    671675   
    672     public function do503($secsToGo, $reason){
     676    public function do503($secsToGo, $reason, $sendEventToCentral = true){
    673677        $this->initLogRequest();
     678
     679        if ($sendEventToCentral) {
     680            do_action('wordfence_security_event', 'block', array(
     681                'ip' => wfUtils::inet_ntop($this->currentRequest->IP),
     682                'reason' => $this->currentRequest->actionDescription ? $this->currentRequest->actionDescription : $reason,
     683                'duration' => $secsToGo,
     684            ));
     685        }
     686
    674687        $this->currentRequest->statusCode = 503;
    675688        if (!$this->currentRequest->action) {
  • wordfence/trunk/lib/wordfenceClass.php

    r2104182 r2107617  
    4242require_once(dirname(__FILE__) . '/wfAdminNoticeQueue.php');
    4343require_once(dirname(__FILE__) . '/wfModuleController.php');
     44require_once(dirname(__FILE__) . '/wfAlerts.php');
    4445
    4546if (version_compare(phpversion(), '5.3', '>=')) {
     
    9697    public static function uninstallPlugin(){
    9798        //Send admin alert
    98         if (wfConfig::get('alertOn_wordfenceDeactivated')) {
    99             $currentUser = wp_get_current_user();
    100             $username = $currentUser->user_login;
    101             wordfence::alert("Wordfence Deactivated", "A user with username \"$username\" deactivated Wordfence on your WordPress site.", wfUtils::getIP());
    102         }
     99        $currentUser = wp_get_current_user();
     100        $username = $currentUser->user_login;
     101        $alertCallback = array(new wfWordfenceDeactivatedAlert($username, wfUtils::getIP()), 'send');
     102        do_action('wordfence_security_event', 'wordfenceDeactivated', array(
     103            'username' => $username,
     104            'ip' => wfUtils::getIP(),
     105        ), $alertCallback);
    103106       
    104107        //Check if caching is enabled and if it is, disable it and fix the .htaccess file.
     
    13111314        add_action('rest_api_init', 'wordfence::initRestAPI');
    13121315
     1316        if (wfCentral::isConnected()) {
     1317            add_action('wordfence_security_event', 'wfCentral::sendSecurityEvent', 10, 3);
     1318        } else {
     1319            add_action('wordfence_security_event', 'wfCentral::sendAlertCallback', 10, 3);
     1320        }
    13131321    }
    13141322    public static function _pluginPageActionLinks($links) {
     
    16651673
    16661674        if($user){
    1667             if(wfConfig::get('alertOn_lostPasswdForm')){
    1668                 wordfence::alert("Password recovery attempted", "Someone tried to recover the password for user with email address: " . wp_kses($user->user_email, array()), $IP);
    1669             }
     1675            $alertCallback = array(new wfLostPasswdFormAlert($user, wfUtils::getIP()), 'send');
     1676            do_action('wordfence_security_event', 'lostPasswdForm', array(
     1677                'email' => $user->user_email,
     1678                'ip' => wfUtils::getIP(),
     1679            ), $alertCallback);
     1680
    16701681        }
    16711682        if(wfConfig::get('loginSecurityEnabled')){
     
    16881699        wfBlock::createLockout($reason, $IP, wfBlock::lockoutDuration(), time(), time(), 1);
    16891700        self::getLog()->tagRequestForLockout($reason);
    1690         if (wfConfig::get('alertOn_loginLockout')) {
    1691             $message = sprintf(__('A user with IP addr %s has been locked out from signing in or using the password recovery form for the following reason: %s.', 'wordfence'), $IP, $reason);
    1692             if (wfBlock::lockoutDuration() > 0) {
    1693                 $message .= "\n" . sprintf(__('The duration of the lockout is %s.', 'wordfence'), wfUtils::makeDuration(wfBlock::lockoutDuration(), true));
    1694             }
    1695             wordfence::alert(__('User locked out from signing in', 'wordfence'), $message, $IP);
    1696         }
     1701        $alertCallback = array(new wfLoginLockoutAlert($IP, $reason), 'send');
     1702        do_action('wordfence_security_event', 'loginLockout', array(
     1703            'ip'       => $IP,
     1704            'reason'   => $reason,
     1705            'duration' => wfBlock::lockoutDuration(),
     1706        ), $alertCallback);
     1707
    16971708    }
    16981709
     
    24032414        $cookievalue = hash_hmac('sha256', $user->user_login, $salt);
    24042415        if(wfUtils::isAdmin($userID)){
    2405             if(wfConfig::get('alertOn_adminLogin')){
    2406                 $shouldAlert = true;
    2407                 if (wfConfig::get('alertOn_firstAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
    2408                     $shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
    2409                 }
    2410                
    2411                 if ($shouldAlert) {
    2412                     wordfence::alert("Admin Login", "A user with username \"$username\" who has administrator access signed in to your WordPress site.", wfUtils::getIP());
    2413                 }
    2414             }
     2416            $securityEvent = 'adminLoginNewLocation';
     2417            if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
     2418                $securityEvent = 'adminLogin';
     2419            }
     2420            $alertCallback = array(new wfAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
     2421            do_action('wordfence_security_event', $securityEvent, array(
     2422                'username' => $username,
     2423                'ip' => wfUtils::getIP(),
     2424            ), $alertCallback);
     2425
    24152426        } else {
    2416             if(wfConfig::get('alertOn_nonAdminLogin')){
    2417                 $shouldAlert = true;
    2418                 if (wfConfig::get('alertOn_firstNonAdminLoginOnly') && isset($_COOKIE[$cookiename])) {
    2419                     $shouldAlert = !hash_equals($cookievalue, $_COOKIE[$cookiename]);
    2420                 }
    2421                
    2422                 if ($shouldAlert) {
    2423                     wordfence::alert("User login", "A non-admin user with username \"$username\" signed in to your WordPress site.", wfUtils::getIP());
    2424                 }
    2425             }
     2427            $securityEvent = 'nonAdminLoginNewLocation';
     2428            if (isset($_COOKIE[$cookiename]) && hash_equals($cookievalue, $_COOKIE[$cookiename])) {
     2429                $securityEvent = 'nonAdminLogin';
     2430            }
     2431            $alertCallback = array(new wfNonAdminLoginAlert($cookiename, $cookievalue, $username, wfUtils::getIP()), 'send');
     2432            do_action('wordfence_security_event', $securityEvent, array(
     2433                'username' => $username,
     2434                'ip' => wfUtils::getIP(),
     2435            ), $alertCallback);
    24262436        }
    24272437       
     
    29232933                        $username = $authUser->user_login;
    29242934                        self::getLog()->logLogin('loginFailValidUsername', 1, $username);
    2925                         if (wfConfig::get('alertOn_breachLogin')) {
    2926                             wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), wfUtils::getIP());
    2927                         }
     2935                        $alertCallback = array(new wfBreachLoginAlert($username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD), wfUtils::getIP()), 'send');
     2936
     2937                        do_action('wordfence_security_event', 'breachLogin', array(
     2938                            'username' => $username,
     2939                            'resetPasswordURL' => wp_lostpassword_url(),
     2940                            'supportURL' => wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD),
     2941                            'ip' => wfUtils::getIP(),
     2942                        ), $alertCallback);
    29282943                       
    29292944                        remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
     
    29522967                $username = $authUser->user_login;
    29532968                self::getLog()->logLogin('loginFailValidUsername', 1, $username);
    2954                 if (wfConfig::get('alertOn_breachLogin')) {
    2955                     wordfence::alert(__('User login blocked for insecure password', 'wordfence'), sprintf(__('A user with username "%s" tried to sign in to your WordPress site. Access was denied because the password being used exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please change or reset the password (%s) to reactivate this account. Learn More: %s', 'wordfence'), $username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), wfUtils::getIP());
    2956                 }
    2957                
     2969                $alertCallback = array(new wfBreachLoginAlert($username, wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD), wfUtils::getIP()), 'send');
     2970
     2971                do_action('wordfence_security_event', 'breachLogin', array(
     2972                    'username' => $username,
     2973                    'resetPasswordURL' => wp_lostpassword_url(),
     2974                    'supportURL' => wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD),
     2975                    'ip' => wfUtils::getIP(),
     2976                ), $alertCallback);
     2977
    29582978                remove_action('login_errors', 'limit_login_fixup_error_messages'); //We're forced to do this because limit-login-attempts does not have any allowances for legitimate error messages
    29592979                self::$authError = new WP_Error('breached_password', sprintf(__('<strong>INSECURE PASSWORD:</strong> Your login attempt has been blocked because the password you are using exists on lists of passwords leaked in data breaches. Attackers use such lists to break into sites and install malicious code. Please <a href="%s">reset your password</a> to reactivate your account. <a href="%s" target="_blank" rel="noopener noreferrer">Learn More</a>'), wp_lostpassword_url(), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)));
     
    78767896                }
    78777897
    7878                 self::alert('Increased Attack Rate', $message, false);
     7898                $alertCallback = array(new wfIncreasedAttackRateAlert($message), 'send');
     7899                do_action('wordfence_security_event', 'increasedAttackRate', array(
     7900                    'attackCount' => $attackCount,
     7901                    'attackTable' => $attackTable,
     7902                    'duration' => $alertInterval,
     7903                    'ip' => wfUtils::getIP(),
     7904                ), $alertCallback);
     7905
    78797906                wfConfig::set('wafAlertLastSendTime', time());
    78807907            }
  • wordfence/trunk/modules/login-security/wordfence-login-security.php

    r2104182 r2107617  
    2828   
    2929    define('WORDFENCE_LS_VERSION', '1.0.2');
    30     define('WORDFENCE_LS_BUILD_NUMBER', '1560275180');
     30    define('WORDFENCE_LS_BUILD_NUMBER', '1560795818');
    3131   
    3232    if (!WORDFENCE_LS_FROM_CORE) {
  • wordfence/trunk/readme.txt

    r2104194 r2107617  
    183183
    184184== Changelog ==
     185
     186= 7.3.4 - June 17, 2019 =
     187* Improvement: Added security events and alerting features built into Wordfence Central.
    185188
    186189= 7.3.3 - June 11, 2019 =
  • wordfence/trunk/wordfence.php

    r2104182 r2107617  
    55Description: Wordfence Security - Anti-virus, Firewall and Malware Scan
    66Author: Wordfence
    7 Version: 7.3.3
     7Version: 7.3.4
    88Author URI: http://www.wordfence.com/
    99Network: true
     
    1616    exit;
    1717}
    18 define('WORDFENCE_VERSION', '7.3.3');
    19 define('WORDFENCE_BUILD_NUMBER', '1560275180');
     18define('WORDFENCE_VERSION', '7.3.4');
     19define('WORDFENCE_BUILD_NUMBER', '1560795818');
    2020define('WORDFENCE_BASENAME', function_exists('plugin_basename') ? plugin_basename(__FILE__) :
    2121    basename(dirname(__FILE__)) . '/' . basename(__FILE__));
Note: See TracChangeset for help on using the changeset viewer.