• Resolved ziegel

    (@ziegel)


    Hi,

    When I login WordPress using MFA, Ninja Fire Wall fails to recognize I’m admin, asks to send notification email, and for some reason WP SES fails to send the email, most likely, as the login just happened, and was postponed by the MFA login.

    The function asking to fire the mail although I’m admin is:

    file ‘ninjafirewall.php’ line 546:

    
    // Check if the user is an admin and if we must whitelist them.
    
    function nfw_login_hook( $user_login, $user ) {
    
    	nfw_session_start();
    
    	$nfw_options = nfw_get_option( 'nfw_options' );
    
    	// Don't do anything if NinjaFirewall is disabled:
    	if ( empty( $nfw_options['enabled'] ) ) { return; }
    
    	// Fetch user roles:
    	$whoami = '';
    	foreach( $user->roles as $k => $v ) {
    		if ( $v == 'administrator' ) {
    			$admin_flag = 1;
    		}
    		$whoami .= "$v ";
    	}
    	$whoami = trim( $whoami );
    
    	// Still nothing: Maybe an additional superadmin
    	if ( empty( $whoami ) && is_multisite() ) {
    		// $user->ID is required here
    		if ( is_super_admin( $user->ID ) ) {
    			$admin_flag = 1;
    			$whoami = 'administrator';
    		}
    	}
    
    	// Are we supposed to send an alert?
    	if (! empty($nfw_options['a_0']) ) {
    		if ( ( $nfw_options['a_0'] == 1 && isset( $admin_flag ) ) || $nfw_options['a_0'] == 2 ) {
    			nfw_send_loginemail( $user_login, $whoami );
    			// Write event to log?
    			if (! empty($nfw_options['a_41']) ) {
    				nfw_log2('Logged in user', "{$user_login} ({$whoami})", 6, 0);
    			}
    		}
    	}
    
    	//Whitelist:
    	if (! empty( $nfw_options['wl_admin']) ) {
    		if ( ( $nfw_options['wl_admin'] == 1 && isset( $admin_flag ) ) || $nfw_options['wl_admin'] == 2 ) {
    			// Set the goodguy flag:
    			$_SESSION['nfw_goodguy'] = 1;
    			return;
    		}
    	}
    
    	// Clear the flag, this user isn't whitelisted:
    	if ( isset( $_SESSION['nfw_goodguy'] ) ) {
    		unset( $_SESSION['nfw_goodguy'] );
    	}
    }

    I managed to find this out, after I deliberately changed the WP SES function name, getting a trace to follow:

    AH01071: Got error 'PHP message: PHP Fatal error: Uncaught Error: Call to undefined method DeliciousBrains\\WP_Offload_SES\\WP_Offload_SES::trigger_queue() in /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/wp-ses/classes/WP-Offload-SES.php:1327\nStack trace:\n#0 /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/wp-ses/wp-ses.php(162): DeliciousBrains\\WP_Offload_SES\\WP_Offload_SES->mail_handler()\n#1 /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/ninjafirewall/lib/utils.php(1660): wp_mail()\n#2 /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/ninjafirewall/lib/utils.php(838): nfw_mail()\n#3 /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/ninjafirewall/ninjafirewall.php(577): nfw_send_loginemail()\n#4 /var/www/vhosts/example.com/staging.example.com/wp-includes/class-wp-hook.php(303): nfw_login_hook()\n#5 /var/www/vhosts/example.com/staging.example.com/wp-includes/class-wp-hook.php(327): WP_Hook->apply_filters()\n#6 /var/www/vhost...PHP message: PHP Fatal error: Uncaught Error: Call to undefined method DeliciousBrains\\WP_Offload_SES\\WP_Offload_SES::trigger_queue() in /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/wp-ses/classes/WP-Offload-SES.php:1327\nStack trace:\n#0 /var/www/vhosts/example.com/staging.example.com/wp-content/plugins/wp-ses/wp-ses.php(162): DeliciousBrains\\WP_Offload_SES\\WP_Offload_SES->mail_handler()\n#1 /var/www/vhosts/example.com/staging.example.com/wp-includes/class-wp-recovery-mode-email-service.php(229): wp_mail()\n#2 /var/www/vhosts/example.com/staging.example.com/wp-includes/class-wp-recovery-mode-email-service.php(61): WP_Recovery_Mode_Email_Service->send_recovery_mode_email()\n#3 /var/www/vhosts/example.com/staging.example.com/wp-includes/class-wp-recovery-mode.php(184): WP_Recovery_Mode_Email_Service->maybe_send_recovery_mode_email()\n#4 /var/www/vhosts/example.com/staging.example.com/wp-includes/class-wp-fatal-error-handler.php(52): WP_Recovery_Mode->handle_error()\n#5 [internal...', referer: https://staging.example.com/wp-login.php

Viewing 3 replies - 1 through 3 (of 3 total)
  • Thread Starter ziegel

    (@ziegel)

    Note: This is the part of the code failing to recognize me as admin when MFA is atciated, and that ‘fires’ an email, which for some reason WP SES fails to take care of, with it

    add_action( 'wp_ajax_wposes_trigger_queue', array( $this, 'maybe_process_queue' ) );
    add_action( 'wp_ajax_nopriv_wposes_trigger_queue', array( $this, 'maybe_process_queue' ) ); 
    

    Mail Handler failing:

    
    /**
    	 * Mail handler
    	 *
    	 * @param string|array $to          The email recipient.
    	 * @param string       $subject     The email subject.
    	 * @param string       $message     The email message.
    	 * @param string|array $headers     The email headers.
    	 * @param string|array $attachments The email attachments.
    	 *
    	 * @return bool
    	 */
    	public function mail_handler( $to, $subject, $message, $headers, $attachments ) {
    		$content_type = apply_filters( 'wp_mail_content_type', 'text/plain' );
    
    		// Add Content-Type header now in case filter is removed by time queue is ran.
    		if ( 'text/html' === $content_type ) {
    			if ( is_array( $headers ) ) {
    				$headers[] = 'Content-Type: text/html;';
    			} else {
    				$headers = "Content-Type: text/html;\n" . $headers;
    			}
    		}
    
    		$subject  = $this->maybe_decode_subject( $subject );
    		$atts     = apply_filters( 'wp_mail', compact( 'to', 'subject', 'message', 'headers', 'attachments' ) );
    		$email_id = $this->get_email_log()->log_email( $atts );
    
    		if ( false === $email_id ) {
    			return false;
    		}
    
    		if ( ! is_array( $attachments ) ) {
    			$attachments = explode( "\n", str_replace( "\r\n", "\n", $attachments ) );
    		}
    
    		foreach ( $attachments as $attachment ) {
    			$this->get_attachments()->handle_attachment( $email_id, $attachment );
    		}
    
    		$this->get_email_queue()->process_email( $email_id );
    		$this->trigger_queue();
    
    		return true;
    	}
    
    	/**
    	 * Sends an async request to trigger the queue if possible.
    	 *
    	 * @return bool
    	 */
    	
    
    	public function trigger_queue() {
    		// Make sure we're not DDOSing our own site.
    		if ( get_transient( 'wposes_triggered_queue' ) ) {
    			return false;
    		}
    
    		set_transient( 'wposes_triggered_queue', true, 10 );
    
    		$data = array(
    			'action' => 'wposes_trigger_queue',
    			'nonce'  => wp_create_nonce( 'wposes_trigger_queue' ),
    		);
    
    		$request_args = apply_filters(
    			'wposes_queue_request',
    			array(
    				'url'  => admin_url( 'admin-ajax.php' ),
    				'args' => array(
    					'timeout'   => 0.01,
    					'blocking'  => false,
    					'sslverify' => apply_filters( 'https_local_ssl_verify', false ),
    					'body'      => $data,
    					'cookies'   => $_COOKIE,
    				),
    			)
    		);
    
    		$result = wp_remote_post( $request_args['url'], $request_args['args'] );
    
    		return ! is_wp_error( $result );
    
    	}
    
    Thread Starter ziegel

    (@ziegel)

    May I suggest the plugin asks to send the email to early on login, where not all code is uploaded?

    Plugin Author nintechnet

    (@nintechnet)

    NinjaFirewall’s hook priority can be user-defined:

    // Hook priority can be defined in the wp-config.php or .htninja
    if ( defined('NFW_LOGINHOOK') ) {
       $NFW_LOGINHOOK = (int) NFW_LOGINHOOK;
    } else {
       $NFW_LOGINHOOK = -999999999;
    }
    add_action( 'wp_login', 'nfw_login_hook', $NFW_LOGINHOOK, 2 );
    

    As you can see, by default it is ‘-999999999’, i.e., it hooks earlier than other plugin. Maybe you could change this value in your wp-config.php and make some tests, for instance:

    define('NFW_LOGINHOOK', X);

    Replace X with the priority you want (the lower, the quicker). Maybe try with 15 or 20. By defaut, WordPress uses 10 (see add_action ).

Viewing 3 replies - 1 through 3 (of 3 total)
  • The topic ‘Ninja FirWall Fails to Recognize I’m Admin on Login –’ is closed to new replies.