Edit File by line

Deprecated: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in /home/sportsfever/public_html/filemanger/function.php on line 93

Warning: Undefined array key "page_file_edit_line" in /home/sportsfever/public_html/filemanger/edit_text_line.php on line 32
/home/sportsfe.../httpdocs/clone/wp-conte.../plugins/wordfenc.../lib
File: wordfenceClass.php
return array($file);
[2500] Fix | Delete
}
[2501] Fix | Delete
return array();
[2502] Fix | Delete
}
[2503] Fix | Delete
[2504] Fix | Delete
if (is_dir($path)) {
[2505] Fix | Delete
$real = realpath($file);
[2506] Fix | Delete
if (in_array($real, $processedDirs)) {
[2507] Fix | Delete
return array();
[2508] Fix | Delete
}
[2509] Fix | Delete
$processedDirs[] = $real;
[2510] Fix | Delete
[2511] Fix | Delete
$count = 0;
[2512] Fix | Delete
$dir = opendir($path);
[2513] Fix | Delete
if ($dir) {
[2514] Fix | Delete
$contents = array();
[2515] Fix | Delete
while ($sub = readdir($dir)) {
[2516] Fix | Delete
if ($sub == '.' || $sub == '..') { continue; }
[2517] Fix | Delete
$contents[] = $sub;
[2518] Fix | Delete
}
[2519] Fix | Delete
closedir($dir);
[2520] Fix | Delete
[2521] Fix | Delete
$filesRemoved = array();
[2522] Fix | Delete
foreach ($contents as $f) {
[2523] Fix | Delete
$removed = self::_recursivelyRemoveWflogs($file . '/' . $f, $processedDirs);
[2524] Fix | Delete
$filesRemoved = array($filesRemoved, $removed);
[2525] Fix | Delete
}
[2526] Fix | Delete
}
[2527] Fix | Delete
[2528] Fix | Delete
if (@rmdir($path)) {
[2529] Fix | Delete
$filesRemoved[] = $file;
[2530] Fix | Delete
}
[2531] Fix | Delete
return $filesRemoved;
[2532] Fix | Delete
}
[2533] Fix | Delete
[2534] Fix | Delete
if (@unlink($path)) {
[2535] Fix | Delete
return array($file);
[2536] Fix | Delete
}
[2537] Fix | Delete
return array();
[2538] Fix | Delete
}
[2539] Fix | Delete
[2540] Fix | Delete
public static function loginAction($username){
[2541] Fix | Delete
if(sizeof($_POST) < 1){ return; } //only execute if login form is posted
[2542] Fix | Delete
if(! $username){ return; }
[2543] Fix | Delete
wfConfig::inc('totalLogins');
[2544] Fix | Delete
$user = get_user_by('login', $username);
[2545] Fix | Delete
$userID = $user ? $user->ID : 0;
[2546] Fix | Delete
self::getLog()->logLogin('loginOK', 0, $username);
[2547] Fix | Delete
if(wfUtils::isAdmin($user)){
[2548] Fix | Delete
wfConfig::set_ser('lastAdminLogin', array(
[2549] Fix | Delete
'userID' => $userID,
[2550] Fix | Delete
'username' => $username,
[2551] Fix | Delete
'firstName' => $user->first_name,
[2552] Fix | Delete
'lastName' => $user->last_name,
[2553] Fix | Delete
'time' => wfUtils::localHumanDateShort(),
[2554] Fix | Delete
'IP' => wfUtils::getIP()
[2555] Fix | Delete
));
[2556] Fix | Delete
}
[2557] Fix | Delete
[2558] Fix | Delete
$salt = wp_salt('logged_in');
[2559] Fix | Delete
//TODO: Drop support for legacy cookie after 1 year
[2560] Fix | Delete
$legacyCookieName = 'wf_loginalerted_' . hash_hmac('sha256', wfUtils::getIP() . '|' . $user->ID, $salt);
[2561] Fix | Delete
$cookieName = 'wf_loginalerted_' . hash_hmac('sha256', $user->ID, $salt);
[2562] Fix | Delete
$cookieValue = hash_hmac('sha256', $user->user_login, $salt);
[2563] Fix | Delete
$newDevice = !(isset($_COOKIE[$legacyCookieName]) && hash_equals($cookieValue, $_COOKIE[$legacyCookieName])); //Check legacy cookie
[2564] Fix | Delete
if($newDevice){
[2565] Fix | Delete
$newDevice = !(isset($_COOKIE[$cookieName]) && hash_equals($cookieValue, $_COOKIE[$cookieName]));
[2566] Fix | Delete
}
[2567] Fix | Delete
else{
[2568] Fix | Delete
$_COOKIE[$cookieName]=$cookieValue;
[2569] Fix | Delete
}
[2570] Fix | Delete
if(wfUtils::isAdmin($userID)){
[2571] Fix | Delete
$securityEvent = 'adminLogin';
[2572] Fix | Delete
$alertCallback = array(new wfAdminLoginAlert($cookieName, $cookieValue, $username, wfUtils::getIP()), 'send');
[2573] Fix | Delete
[2574] Fix | Delete
} else {
[2575] Fix | Delete
$securityEvent = 'nonAdminLogin';
[2576] Fix | Delete
$alertCallback = array(new wfNonAdminLoginAlert($cookieName, $cookieValue, $username, wfUtils::getIP()), 'send');
[2577] Fix | Delete
}
[2578] Fix | Delete
if($newDevice)
[2579] Fix | Delete
$securityEvent.='NewLocation';
[2580] Fix | Delete
do_action('wordfence_security_event', $securityEvent, array(
[2581] Fix | Delete
'username' => $username,
[2582] Fix | Delete
'ip' => wfUtils::getIP(),
[2583] Fix | Delete
), $alertCallback);
[2584] Fix | Delete
[2585] Fix | Delete
if (wfConfig::get(wfUtils::isAdmin($userID)?'alertOn_firstAdminLoginOnly':'alertOn_firstNonAdminLoginOnly')) {
[2586] Fix | Delete
//Purge legacy cookie if still present
[2587] Fix | Delete
if(array_key_exists($legacyCookieName, $_COOKIE))
[2588] Fix | Delete
wfUtils::setcookie($legacyCookieName, '', 1, '/', null, wfUtils::isFullSSL(), true);
[2589] Fix | Delete
wfUtils::setcookie($cookieName, $cookieValue, time() + (86400 * 365), '/', null, wfUtils::isFullSSL(), true);
[2590] Fix | Delete
}
[2591] Fix | Delete
}
[2592] Fix | Delete
public static function registrationFilter($errors, $sanitizedLogin, $userEmail) {
[2593] Fix | Delete
if (wfConfig::get('loginSec_blockAdminReg') && $sanitizedLogin == 'admin') {
[2594] Fix | Delete
$errors->add('user_login_error', __('<strong>ERROR</strong>: You can\'t register using that username', 'wordfence'));
[2595] Fix | Delete
}
[2596] Fix | Delete
return $errors;
[2597] Fix | Delete
}
[2598] Fix | Delete
public static function wooRegistrationFilter($wooCustomerData) {
[2599] Fix | Delete
/*
[2600] Fix | Delete
$wooCustomerData matches:
[2601] Fix | Delete
array(
[2602] Fix | Delete
'user_login' => $username,
[2603] Fix | Delete
'user_pass' => $password,
[2604] Fix | Delete
'user_email' => $email,
[2605] Fix | Delete
'role' => 'customer',
[2606] Fix | Delete
)
[2607] Fix | Delete
*/
[2608] Fix | Delete
if (wfConfig::get('loginSec_blockAdminReg') && is_array($wooCustomerData) && isset($wooCustomerData['user_login']) && isset($wooCustomerData['user_email']) && preg_match('/^admin\d*$/i', $wooCustomerData['user_login'])) {
[2609] Fix | Delete
//Converts a username of `admin` generated from something like `admin@example.com` to `adminexample`
[2610] Fix | Delete
$emailComponents = explode('@', $wooCustomerData['user_email']);
[2611] Fix | Delete
if (strpos(wfUtils::array_last($emailComponents), '.') === false) { //e.g., admin@localhost
[2612] Fix | Delete
$wooCustomerData['user_login'] .= wfUtils::array_last($emailComponents);
[2613] Fix | Delete
}
[2614] Fix | Delete
else { //e.g., admin@example.com
[2615] Fix | Delete
$hostComponents = explode('.', wfUtils::array_last($emailComponents));
[2616] Fix | Delete
array_pop($hostComponents);
[2617] Fix | Delete
$wooCustomerData['user_login'] .= wfUtils::array_last($hostComponents);
[2618] Fix | Delete
}
[2619] Fix | Delete
[2620] Fix | Delete
//If it's still `admin` at this point, it will fall through and get blocked by wordfence::blacklistedUsernames
[2621] Fix | Delete
}
[2622] Fix | Delete
return $wooCustomerData;
[2623] Fix | Delete
}
[2624] Fix | Delete
public static function oembedAuthorFilter($data, $post, $width, $height) {
[2625] Fix | Delete
unset($data['author_name']);
[2626] Fix | Delete
unset($data['author_url']);
[2627] Fix | Delete
return $data;
[2628] Fix | Delete
}
[2629] Fix | Delete
public static function jsonAPIAuthorFilter($response, $handler, $request) {
[2630] Fix | Delete
$route = $request->get_route();
[2631] Fix | Delete
if (!current_user_can('edit_others_posts')) {
[2632] Fix | Delete
$urlBase = wfWP_REST_Users_Controller::wfGetURLBase();
[2633] Fix | Delete
if (preg_match('~' . preg_quote($urlBase, '~') . '/*$~i', $route)) {
[2634] Fix | Delete
$error = new WP_Error('rest_user_cannot_view', __('Sorry, you are not allowed to list users.', 'wordfence'), array('status' => rest_authorization_required_code()));
[2635] Fix | Delete
$response = rest_ensure_response($error);
[2636] Fix | Delete
if (!defined('WORDFENCE_REST_API_SUPPRESSED')) { define('WORDFENCE_REST_API_SUPPRESSED', true); }
[2637] Fix | Delete
}
[2638] Fix | Delete
else if (preg_match('~' . preg_quote($urlBase, '~') . '/+(\d+)/*$~i', $route, $matches)) {
[2639] Fix | Delete
$id = (int) $matches[1];
[2640] Fix | Delete
if (get_current_user_id() !== $id) {
[2641] Fix | Delete
$error = new WP_Error('rest_user_invalid_id', __('Invalid user ID.', 'wordfence'), array('status' => 404));
[2642] Fix | Delete
$response = rest_ensure_response($error);
[2643] Fix | Delete
if (!defined('WORDFENCE_REST_API_SUPPRESSED')) { define('WORDFENCE_REST_API_SUPPRESSED', true); }
[2644] Fix | Delete
}
[2645] Fix | Delete
}
[2646] Fix | Delete
}
[2647] Fix | Delete
return $response;
[2648] Fix | Delete
}
[2649] Fix | Delete
public static function jsonAPIAdjustHeaders($response, $server, $request) {
[2650] Fix | Delete
if (defined('WORDFENCE_REST_API_SUPPRESSED')) {
[2651] Fix | Delete
$response->header('Allow', 'GET');
[2652] Fix | Delete
}
[2653] Fix | Delete
[2654] Fix | Delete
return $response;
[2655] Fix | Delete
}
[2656] Fix | Delete
public static function wpSitemapUserProviderFilter($provider, $name) {
[2657] Fix | Delete
if ($name === 'users') {
[2658] Fix | Delete
return false;
[2659] Fix | Delete
}
[2660] Fix | Delete
return $provider;
[2661] Fix | Delete
}
[2662] Fix | Delete
public static function _filterCentralFromLiveTraffic($dispatch_result, $request, $route, $handler) {
[2663] Fix | Delete
if (preg_match('~^/wordfence/v\d+/~i', $route)) {
[2664] Fix | Delete
self::getLog()->canLogHit = false;
[2665] Fix | Delete
}
[2666] Fix | Delete
return $dispatch_result;
[2667] Fix | Delete
}
[2668] Fix | Delete
public static function showTwoFactorField() {
[2669] Fix | Delete
$existingContents = ob_get_contents();
[2670] Fix | Delete
if (!preg_match('/wftwofactornonce:([0-9]+)\/(.+?)\s/', $existingContents, $matches)) {
[2671] Fix | Delete
return;
[2672] Fix | Delete
}
[2673] Fix | Delete
[2674] Fix | Delete
$userID = intval($matches[1]);
[2675] Fix | Delete
$twoFactorNonce = preg_replace('/[^a-f0-9]/i', '', $matches[2]);
[2676] Fix | Delete
if (!self::verifyTwoFactorIntermediateValues($userID, $twoFactorNonce)) {
[2677] Fix | Delete
return;
[2678] Fix | Delete
}
[2679] Fix | Delete
[2680] Fix | Delete
//Strip out the username and password fields
[2681] Fix | Delete
$formPosition = strrpos($existingContents, '<form');
[2682] Fix | Delete
$formTagEnd = strpos($existingContents, '>', $formPosition);
[2683] Fix | Delete
if ($formPosition === false || $formTagEnd === false) {
[2684] Fix | Delete
return;
[2685] Fix | Delete
}
[2686] Fix | Delete
[2687] Fix | Delete
ob_end_clean();
[2688] Fix | Delete
ob_start();
[2689] Fix | Delete
echo substr($existingContents, 0, $formTagEnd + 1);
[2690] Fix | Delete
[2691] Fix | Delete
//Add the 2FA field
[2692] Fix | Delete
echo "<p>
[2693] Fix | Delete
<label for=\"wfAuthenticationCode\">Authentication Code<br>
[2694] Fix | Delete
<input type=\"text\" size=\"6\" class=\"input\" id=\"wordfence_authFactor\" name=\"wordfence_authFactor\" autofocus></label>
[2695] Fix | Delete
<input type=\"hidden\" id=\"wordfence_twoFactorUser\" name=\"wordfence_twoFactorUser\" value=\"" . $userID . "\">
[2696] Fix | Delete
<input type=\"hidden\" id=\"wordfence_twoFactorNonce\" name=\"wordfence_twoFactorNonce\" value=\"" . $twoFactorNonce . "\">
[2697] Fix | Delete
</p>";
[2698] Fix | Delete
}
[2699] Fix | Delete
private static function verifyTwoFactorIntermediateValues($userID, $twoFactorNonce) {
[2700] Fix | Delete
$user = get_user_by('ID', $userID);
[2701] Fix | Delete
if (!$user || get_class($user) != 'WP_User') { return false; } //Check that the user exists
[2702] Fix | Delete
[2703] Fix | Delete
$expectedNonce = get_user_meta($user->ID, '_wf_twoFactorNonce', true);
[2704] Fix | Delete
$twoFactorNonceTime = get_user_meta($user->ID, '_wf_twoFactorNonceTime', true);
[2705] Fix | Delete
if (empty($twoFactorNonce) || empty($twoFactorNonceTime)) { return false; } //Ensure the two factor nonce and time have been set
[2706] Fix | Delete
if ($twoFactorNonce != $expectedNonce) { return false; } //Verify the nonce matches the expected
[2707] Fix | Delete
[2708] Fix | Delete
$twoFactorUsers = wfConfig::get_ser('twoFactorUsers', array());
[2709] Fix | Delete
if (!$twoFactorUsers || !is_array($twoFactorUsers)) { return false; } //Make sure there are two factor users configured
[2710] Fix | Delete
foreach ($twoFactorUsers as &$t) { //Ensure the two factor nonce hasn't expired
[2711] Fix | Delete
if ($t[0] == $user->ID && $t[3] == 'activated') {
[2712] Fix | Delete
if (isset($t[5]) && $t[5] == 'authenticator') { $graceTime = WORDFENCE_TWO_FACTOR_GRACE_TIME_AUTHENTICATOR; }
[2713] Fix | Delete
else { $graceTime = WORDFENCE_TWO_FACTOR_GRACE_TIME_PHONE; }
[2714] Fix | Delete
return ((time() - $twoFactorNonceTime) < $graceTime);
[2715] Fix | Delete
}
[2716] Fix | Delete
}
[2717] Fix | Delete
return false;
[2718] Fix | Delete
}
[2719] Fix | Delete
public static function authenticateFilter($authUser, $username, $passwd) {
[2720] Fix | Delete
wfConfig::inc('totalLoginHits'); //The total hits to wp-login.php including logins, logouts and just hits.
[2721] Fix | Delete
$IP = wfUtils::getIP();
[2722] Fix | Delete
$secEnabled = wfConfig::get('loginSecurityEnabled');
[2723] Fix | Delete
[2724] Fix | Delete
$twoFactorUsers = wfConfig::get_ser('twoFactorUsers', array());
[2725] Fix | Delete
$userDat = self::$userDat;
[2726] Fix | Delete
[2727] Fix | Delete
$checkBreachList = $secEnabled &&
[2728] Fix | Delete
!wfBlock::isWhitelisted($IP) &&
[2729] Fix | Delete
wfConfig::get('loginSec_breachPasswds_enabled') &&
[2730] Fix | Delete
is_object($authUser) &&
[2731] Fix | Delete
get_class($authUser) == 'WP_User' &&
[2732] Fix | Delete
((wfConfig::get('loginSec_breachPasswds') == 'admins' && wfUtils::isAdmin($authUser)) || (wfConfig::get('loginSec_breachPasswds') == 'pubs' && user_can($authUser, 'publish_posts')));
[2733] Fix | Delete
[2734] Fix | Delete
$usingBreachedPassword = false;
[2735] Fix | Delete
if ($checkBreachList) {
[2736] Fix | Delete
$cacheStatus = wfCredentialsController::cachedCredentialStatus($authUser);
[2737] Fix | Delete
if ($cacheStatus != wfCredentialsController::UNCACHED) {
[2738] Fix | Delete
$usingBreachedPassword = ($cacheStatus == wfCredentialsController::LEAKED);
[2739] Fix | Delete
}
[2740] Fix | Delete
else {
[2741] Fix | Delete
if (wfCredentialsController::isLeakedPassword($authUser->username, $passwd)) {
[2742] Fix | Delete
$usingBreachedPassword = true;
[2743] Fix | Delete
}
[2744] Fix | Delete
wfCredentialsController::setCachedCredentialStatus($authUser, $usingBreachedPassword);
[2745] Fix | Delete
}
[2746] Fix | Delete
}
[2747] Fix | Delete
[2748] Fix | Delete
$checkTwoFactor = $secEnabled &&
[2749] Fix | Delete
!wfBlock::isWhitelisted($IP) &&
[2750] Fix | Delete
wfConfig::get('isPaid') &&
[2751] Fix | Delete
isset($twoFactorUsers) &&
[2752] Fix | Delete
is_array($twoFactorUsers) &&
[2753] Fix | Delete
sizeof($twoFactorUsers) > 0 &&
[2754] Fix | Delete
is_object($userDat) &&
[2755] Fix | Delete
get_class($userDat) == 'WP_User' &&
[2756] Fix | Delete
wfCredentialsController::useLegacy2FA();
[2757] Fix | Delete
[2758] Fix | Delete
if ($checkTwoFactor) {
[2759] Fix | Delete
$twoFactorRecord = false;
[2760] Fix | Delete
$hasActivatedTwoFactorUser = false;
[2761] Fix | Delete
foreach ($twoFactorUsers as &$t) {
[2762] Fix | Delete
if ($t[3] == 'activated') {
[2763] Fix | Delete
$userID = $t[0];
[2764] Fix | Delete
$testUser = get_user_by('ID', $userID);
[2765] Fix | Delete
if (is_object($testUser) && wfUtils::isAdmin($testUser)) {
[2766] Fix | Delete
$hasActivatedTwoFactorUser = true;
[2767] Fix | Delete
}
[2768] Fix | Delete
[2769] Fix | Delete
if ($userID == $userDat->ID) {
[2770] Fix | Delete
$twoFactorRecord = &$t;
[2771] Fix | Delete
}
[2772] Fix | Delete
}
[2773] Fix | Delete
}
[2774] Fix | Delete
[2775] Fix | Delete
if (isset($_POST['wordfence_authFactor']) && $_POST['wordfence_authFactor'] && $twoFactorRecord) { //User authenticated with name and password, 2FA code ready to check
[2776] Fix | Delete
$userID = $userDat->ID;
[2777] Fix | Delete
[2778] Fix | Delete
if (is_object($authUser) && get_class($authUser) == 'WP_User' && $authUser->ID == $userID) {
[2779] Fix | Delete
//Do nothing. This is the code path the old method of including the code in the password field will take -- since we already have a valid $authUser, skip the nonce verification portion
[2780] Fix | Delete
}
[2781] Fix | Delete
else if (isset($_POST['wordfence_twoFactorNonce'])) {
[2782] Fix | Delete
$twoFactorNonce = preg_replace('/[^a-f0-9]/i', '', $_POST['wordfence_twoFactorNonce']);
[2783] Fix | Delete
if (!self::verifyTwoFactorIntermediateValues($userID, $twoFactorNonce)) {
[2784] Fix | Delete
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
[2785] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>VERIFICATION FAILED</strong>: Two-factor authentication verification failed. Please try again.', 'wordfence'), array('strong'=>array())));
[2786] Fix | Delete
return self::processBruteForceAttempt(self::$authError, $username, $passwd);
[2787] Fix | Delete
}
[2788] Fix | Delete
}
[2789] Fix | Delete
else { //Code path for old method, invalid password the second time
[2790] Fix | Delete
self::$authError = $authUser;
[2791] Fix | Delete
if (is_wp_error(self::$authError) && (self::$authError->get_error_code() == 'invalid_username' || $authUser->get_error_code() == 'invalid_email' || self::$authError->get_error_code() == 'incorrect_password' || $authUser->get_error_code() == 'authentication_failed') && wfConfig::get('loginSec_maskLoginErrors')) {
[2792] Fix | Delete
self::$authError = new WP_Error('incorrect_password', sprintf(/* translators: 1. WordPress username. 2. Password reset URL. */ wp_kses(__('<strong>ERROR</strong>: The username or password you entered is incorrect. <a href="%2$s" title="Password Lost and Found">Lost your password</a>?', 'wordfence'), array('strong'=>array(), 'a'=>array('href'=>array(), 'title'=>array()))), $username, wp_lostpassword_url()));
[2793] Fix | Delete
}
[2794] Fix | Delete
[2795] Fix | Delete
return self::processBruteForceAttempt(self::$authError, $username, $passwd);
[2796] Fix | Delete
}
[2797] Fix | Delete
[2798] Fix | Delete
if ($usingBreachedPassword) {
[2799] Fix | Delete
wfAdminNoticeQueue::removeAdminNotice(false, 'previousIPBreachPassword', array($userID));
[2800] Fix | Delete
wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(
[2801] Fix | Delete
/* translators: 1. WordPress admin panel URL. 2. Support URL. */
[2802] Fix | Delete
__('<strong>WARNING: </strong>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="%1$s">change your password</a>. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'),
[2803] Fix | Delete
self_admin_url('profile.php'),
[2804] Fix | Delete
wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)
[2805] Fix | Delete
), '2faBreachPassword', array($authUser->ID));
[2806] Fix | Delete
}
[2807] Fix | Delete
[2808] Fix | Delete
if (isset($twoFactorRecord[5])) { //New method TOTP
[2809] Fix | Delete
$mode = $twoFactorRecord[5];
[2810] Fix | Delete
$code = preg_replace('/[^a-f0-9]/i', '', $_POST['wordfence_authFactor']);
[2811] Fix | Delete
[2812] Fix | Delete
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
[2813] Fix | Delete
try {
[2814] Fix | Delete
$codeResult = $api->call('twoFactorTOTP_verify', array(), array('totpid' => $twoFactorRecord[6], 'code' => $code, 'mode' => $mode));
[2815] Fix | Delete
[2816] Fix | Delete
if (isset($codeResult['notPaid']) && $codeResult['notPaid']) {
[2817] Fix | Delete
//No longer a paid key, let them sign in without two factor
[2818] Fix | Delete
}
[2819] Fix | Delete
else if (isset($codeResult['ok']) && $codeResult['ok']) {
[2820] Fix | Delete
//Everything's good, let the sign in continue
[2821] Fix | Delete
}
[2822] Fix | Delete
else {
[2823] Fix | Delete
if (is_object($authUser) && get_class($authUser) == 'WP_User' && $authUser->ID == $userID) { //Using the old method of appending the code to the password
[2824] Fix | Delete
if ($mode == 'authenticator') {
[2825] Fix | Delete
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
[2826] Fix | Delete
self::$authError = new WP_Error('twofactor_invalid', wp_kses(__('<strong>INVALID CODE</strong>: Please sign in again and add a space, the letters <code>wf</code>, and the code from your authenticator app to the end of your password (e.g., <code>wf123456</code>).', 'wordfence'), array('strong'=>array(), 'code'=>array())));
[2827] Fix | Delete
}
[2828] Fix | Delete
else {
[2829] Fix | Delete
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
[2830] Fix | Delete
self::$authError = new WP_Error('twofactor_invalid', wp_kses(__('<strong>INVALID CODE</strong>: Please sign in again and add a space, the letters <code>wf</code>, and the code sent to your phone to the end of your password (e.g., <code>wf123456</code>).', 'wordfence'), array('strong'=>array(), 'code'=>array())));
[2831] Fix | Delete
}
[2832] Fix | Delete
}
[2833] Fix | Delete
else {
[2834] Fix | Delete
$loginNonce = wfWAFUtils::random_bytes(20);
[2835] Fix | Delete
if ($loginNonce === false) { //Should never happen but is technically possible
[2836] Fix | Delete
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
[2837] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>AUTHENTICATION FAILURE</strong>: A temporary failure was encountered while trying to log in. Please try again.', 'wordfence'), array('strong'=>array())));
[2838] Fix | Delete
return self::$authError;
[2839] Fix | Delete
}
[2840] Fix | Delete
[2841] Fix | Delete
$loginNonce = bin2hex($loginNonce);
[2842] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonce', $loginNonce);
[2843] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonceTime', time());
[2844] Fix | Delete
[2845] Fix | Delete
if ($mode == 'authenticator') {
[2846] Fix | Delete
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
[2847] Fix | Delete
self::$authError = new WP_Error('twofactor_invalid', wp_kses(__('<strong>INVALID CODE</strong>: You need to enter the code generated by your authenticator app. The code should be a six digit number (e.g., 123456).', 'wordfence'), array('strong'=>array())) . '<!-- wftwofactornonce:' . $userDat->ID . '/' . $loginNonce . ' -->');
[2848] Fix | Delete
}
[2849] Fix | Delete
else {
[2850] Fix | Delete
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
[2851] Fix | Delete
self::$authError = new WP_Error('twofactor_invalid', wp_kses(__('<strong>INVALID CODE</strong>: You need to enter the code generated sent to your phone. The code should be a six digit number (e.g., 123456).', 'wordfence'), array('strong'=>array())) . '<!-- wftwofactornonce:' . $userDat->ID . '/' . $loginNonce . ' -->');
[2852] Fix | Delete
}
[2853] Fix | Delete
}
[2854] Fix | Delete
return self::processBruteForceAttempt(self::$authError, $username, $passwd);
[2855] Fix | Delete
}
[2856] Fix | Delete
}
[2857] Fix | Delete
catch (Exception $e) {
[2858] Fix | Delete
if (self::isDebugOn()) {
[2859] Fix | Delete
error_log('TOTP validation error: ' . $e->getMessage());
[2860] Fix | Delete
}
[2861] Fix | Delete
} // Couldn't connect to noc1, let them sign in since the password was correct.
[2862] Fix | Delete
}
[2863] Fix | Delete
else { //Old method phone authentication
[2864] Fix | Delete
$authFactor = $_POST['wordfence_authFactor'];
[2865] Fix | Delete
if (strlen($authFactor) == 4) {
[2866] Fix | Delete
$authFactor = 'wf' . $authFactor;
[2867] Fix | Delete
}
[2868] Fix | Delete
if ($authFactor == $twoFactorRecord[2] && $twoFactorRecord[4] > time()) { // Set this 2FA code to expire in 30 seconds (for other plugins hooking into the auth process)
[2869] Fix | Delete
$twoFactorRecord[4] = time() + 30;
[2870] Fix | Delete
wfConfig::set_ser('twoFactorUsers', $twoFactorUsers);
[2871] Fix | Delete
}
[2872] Fix | Delete
else if ($authFactor == $twoFactorRecord[2]) {
[2873] Fix | Delete
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
[2874] Fix | Delete
try {
[2875] Fix | Delete
$codeResult = $api->call('twoFactor_verification', array(), array('phone' => $twoFactorRecord[1]));
[2876] Fix | Delete
[2877] Fix | Delete
if (isset($codeResult['notPaid']) && $codeResult['notPaid']) {
[2878] Fix | Delete
//No longer a paid key, let them sign in without two factor
[2879] Fix | Delete
}
[2880] Fix | Delete
else if (isset($codeResult['ok']) && $codeResult['ok']) {
[2881] Fix | Delete
$twoFactorRecord[2] = $codeResult['code'];
[2882] Fix | Delete
$twoFactorRecord[4] = time() + 1800; //30 minutes until code expires
[2883] Fix | Delete
wfConfig::set_ser('twoFactorUsers', $twoFactorUsers); //save the code the user needs to enter and return an error.
[2884] Fix | Delete
[2885] Fix | Delete
$loginNonce = wfWAFUtils::random_bytes(20);
[2886] Fix | Delete
if ($loginNonce === false) { //Should never happen but is technically possible
[2887] Fix | Delete
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
[2888] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>AUTHENTICATION FAILURE</strong>: A temporary failure was encountered while trying to log in. Please try again.', 'wordfence'), array('strong'=>array())));
[2889] Fix | Delete
return self::$authError;
[2890] Fix | Delete
}
[2891] Fix | Delete
[2892] Fix | Delete
$loginNonce = bin2hex($loginNonce);
[2893] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonce', $loginNonce);
[2894] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonceTime', time());
[2895] Fix | Delete
[2896] Fix | Delete
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
[2897] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>CODE EXPIRED. CHECK YOUR PHONE:</strong> The code you entered has expired. Codes are only valid for 30 minutes for security reasons. We have sent you a new code. Please sign in using your username, password, and the new code we sent you.', 'wordfence'), array('strong'=>array())) . '<!-- wftwofactornonce:' . $userDat->ID . '/' . $loginNonce . ' -->');
[2898] Fix | Delete
return self::$authError;
[2899] Fix | Delete
}
[2900] Fix | Delete
[2901] Fix | Delete
//else: No new code was received. Let them sign in with the expired code.
[2902] Fix | Delete
}
[2903] Fix | Delete
catch (Exception $e) {
[2904] Fix | Delete
// Couldn't connect to noc1, let them sign in since the password was correct.
[2905] Fix | Delete
}
[2906] Fix | Delete
}
[2907] Fix | Delete
else { //Bad code, so cancel the login and return an error to user.
[2908] Fix | Delete
$loginNonce = wfWAFUtils::random_bytes(20);
[2909] Fix | Delete
if ($loginNonce === false) { //Should never happen but is technically possible
[2910] Fix | Delete
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
[2911] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>AUTHENTICATION FAILURE</strong>: A temporary failure was encountered while trying to log in. Please try again.', 'wordfence'), array('strong'=>array())));
[2912] Fix | Delete
return self::$authError;
[2913] Fix | Delete
}
[2914] Fix | Delete
[2915] Fix | Delete
$loginNonce = bin2hex($loginNonce);
[2916] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonce', $loginNonce);
[2917] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonceTime', time());
[2918] Fix | Delete
[2919] Fix | Delete
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
[2920] Fix | Delete
self::$authError = new WP_Error('twofactor_invalid', wp_kses(__('<strong>INVALID CODE</strong>: You need to enter your password and the code we sent to your phone. The code should start with \'wf\' and should be four characters (e.g., wfAB12).', 'wordfence'), array('strong'=>array())) . '<!-- wftwofactornonce:' . $userDat->ID . '/' . $loginNonce . ' -->');
[2921] Fix | Delete
return self::processBruteForceAttempt(self::$authError, $username, $passwd);
[2922] Fix | Delete
}
[2923] Fix | Delete
}
[2924] Fix | Delete
delete_user_meta($userDat->ID, '_wf_twoFactorNonce');
[2925] Fix | Delete
delete_user_meta($userDat->ID, '_wf_twoFactorNonceTime');
[2926] Fix | Delete
$authUser = $userDat; //Log in as the user we saved in the wp_authenticate action
[2927] Fix | Delete
}
[2928] Fix | Delete
else if (is_object($authUser) && get_class($authUser) == 'WP_User') { //User authenticated with name and password, prompt for the 2FA code
[2929] Fix | Delete
//Verify at least one administrator has 2FA enabled
[2930] Fix | Delete
$requireAdminTwoFactor = $hasActivatedTwoFactorUser && wfConfig::get('loginSec_requireAdminTwoFactor');
[2931] Fix | Delete
[2932] Fix | Delete
if ($twoFactorRecord) {
[2933] Fix | Delete
if ($twoFactorRecord[0] == $userDat->ID && $twoFactorRecord[3] == 'activated') { //Yup, enabled, so require the code
[2934] Fix | Delete
if ($usingBreachedPassword) {
[2935] Fix | Delete
wfAdminNoticeQueue::removeAdminNotice(false, 'previousIPBreachPassword', array($authUser->ID));
[2936] Fix | Delete
wfAdminNoticeQueue::addAdminNotice(wfAdminNotice::SEVERITY_CRITICAL, sprintf(
[2937] Fix | Delete
/* translators: 1. WordPress admin panel URL. 2. Support URL. */
[2938] Fix | Delete
__('<strong>WARNING: </strong>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="%1$s">change your password</a>. <a href="%2$s" target="_blank" rel="noopener noreferrer">Learn More<span class="screen-reader-text"> (' . esc_html__('opens in new tab', 'wordfence') . ')</span></a>', 'wordfence'), self_admin_url('profile.php'), wfSupportController::esc_supportURL(wfSupportController::ITEM_USING_BREACH_PASSWORD)), '2faBreachPassword', array($authUser->ID));
[2939] Fix | Delete
}
[2940] Fix | Delete
[2941] Fix | Delete
$loginNonce = wfWAFUtils::random_bytes(20);
[2942] Fix | Delete
if ($loginNonce === false) { //Should never happen but is technically possible, allow login
[2943] Fix | Delete
$requireAdminTwoFactor = false;
[2944] Fix | Delete
}
[2945] Fix | Delete
else {
[2946] Fix | Delete
$loginNonce = bin2hex($loginNonce);
[2947] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonce', $loginNonce);
[2948] Fix | Delete
update_user_meta($userDat->ID, '_wf_twoFactorNonceTime', time());
[2949] Fix | Delete
[2950] Fix | Delete
if (isset($twoFactorRecord[5])) { //New method TOTP authentication
[2951] Fix | Delete
if ($twoFactorRecord[5] == 'authenticator') {
[2952] Fix | Delete
if (self::hasGDLimitLoginsMUPlugin() && function_exists('limit_login_get_address')) {
[2953] Fix | Delete
$retries = get_option('limit_login_retries', array());
[2954] Fix | Delete
$ip = limit_login_get_address();
[2955] Fix | Delete
[2956] Fix | Delete
if (!is_array($retries)) {
[2957] Fix | Delete
$retries = array();
[2958] Fix | Delete
}
[2959] Fix | Delete
if (isset($retries[$ip]) && is_int($retries[$ip])) {
[2960] Fix | Delete
$retries[$ip]--;
[2961] Fix | Delete
}
[2962] Fix | Delete
else {
[2963] Fix | Delete
$retries[$ip] = 0;
[2964] Fix | Delete
}
[2965] Fix | Delete
update_option('limit_login_retries', $retries);
[2966] Fix | Delete
}
[2967] Fix | Delete
[2968] Fix | Delete
$allowSeparatePrompt = ini_get('output_buffering') > 0;
[2969] Fix | Delete
if (wfConfig::get('loginSec_enableSeparateTwoFactor') && $allowSeparatePrompt) {
[2970] Fix | Delete
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
[2971] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>CODE REQUIRED</strong>: Please check your authenticator app for the current code. Enter it below to sign in.', 'wordfence'), array('strong'=>array())) . '<!-- wftwofactornonce:' . $userDat->ID . '/' . $loginNonce . ' -->');
[2972] Fix | Delete
return self::$authError;
[2973] Fix | Delete
}
[2974] Fix | Delete
else {
[2975] Fix | Delete
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
[2976] Fix | Delete
self::$authError = new WP_Error('twofactor_required', wp_kses(__('<strong>CODE REQUIRED</strong>: Please check your authenticator app for the current code. Please sign in again and add a space, the letters <code>wf</code>, and the code to the end of your password (e.g., <code>wf123456</code>).', 'wordfence'), array('strong'=>array(), 'code'=>array())));
[2977] Fix | Delete
return self::$authError;
[2978] Fix | Delete
}
[2979] Fix | Delete
}
[2980] Fix | Delete
else {
[2981] Fix | Delete
//Phone TOTP
[2982] Fix | Delete
$api = new wfAPI(wfConfig::get('apiKey'), wfUtils::getWPVersion());
[2983] Fix | Delete
try {
[2984] Fix | Delete
$codeResult = $api->call('twoFactorTOTP_sms', array(), array('totpid' => $twoFactorRecord[6]));
[2985] Fix | Delete
if (isset($codeResult['notPaid']) && $codeResult['notPaid']) {
[2986] Fix | Delete
$requireAdminTwoFactor = false;
[2987] Fix | Delete
//Let them sign in without two factor if their API key has expired or they're not paid and for some reason they have this set up.
[2988] Fix | Delete
}
[2989] Fix | Delete
else {
[2990] Fix | Delete
if (isset($codeResult['ok']) && $codeResult['ok']) {
[2991] Fix | Delete
if (self::hasGDLimitLoginsMUPlugin() && function_exists('limit_login_get_address')) {
[2992] Fix | Delete
$retries = get_option('limit_login_retries', array());
[2993] Fix | Delete
$ip = limit_login_get_address();
[2994] Fix | Delete
[2995] Fix | Delete
if (!is_array($retries)) {
[2996] Fix | Delete
$retries = array();
[2997] Fix | Delete
}
[2998] Fix | Delete
if (isset($retries[$ip]) && is_int($retries[$ip])) {
[2999] Fix | Delete
It is recommended that you Edit text format, this type of Fix handles quite a lot in one request
Function