Support » Plugin: iThemes Security » IP Detection does not work

  • Resolved Robert

    (@whi73rav3n)


    Hello,

    I am trying to make use of the IP Detection feature since I am behind a Cloudfront instance and no matter the setting I always get the IPs of the load balancer and not of the actual user.

    Running a simple PHP script off the Internet provides the correct information. This is the script I am running and always finds the correct information in the X-FORWARDED-FOR header as per the Cloudfront documentation.

    <?php
    foreach (
    			array(
    				'HTTP_CLIENT_IP',
    				'HTTP_X_FORWARDED_FOR',
    				'HTTP_X_FORWARDED',
    				'HTTP_X_CLUSTER_CLIENT_IP',
    				'HTTP_FORWARDED_FOR',
    				'HTTP_FORWARDED',
    				'REMOTE_ADDR'
    			) as $key
    		) {
    			if ( array_key_exists( $key, $_SERVER ) === true ) {
    				foreach ( explode( ',', $_SERVER[ $key ] ) as $ip ) {
    					$ip = trim( $ip ); // just to be safe
    					if ( filter_var( $ip, FILTER_VALIDATE_IP,
    							FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE ) !== false
    					) {
    						return $ip;
    					}
    				}
    			}
    		}

    Can you look into the problem?

    Thank you!

Viewing 15 replies - 1 through 15 (of 30 total)
  • Hi @whi73rav3n,

    I am trying to make use of the IP Detection feature since I am behind a Cloudfront instance and no matter the setting I always get the IPs of the load balancer and not of the actual user.

    So selecting PROXY DETECTION = Manual and then PROXY HEADER = X-Forwarded-For does not work (don’t forget to save)?

    If so navigate to Security > Settings > Tools and try and run Security Check Pro (it’s the last tool at the bottom).

    +++++ To prevent any confusion, I’m not iThemes +++++

    Thread Starter Robert

    (@whi73rav3n)

    Hi @nlpro

    The X-Forwarded-For does not work since it obtains the IP address of the load balancer.

    As for your suggestion, I do not have that option under the Tools section of the plugin.

    Thank you!

    Hi @whi73rav3n,

    Ok, I see. Can you verify whether the actual client IP address exists (at all) in the X-Forwarded-For header of a request ? (Your working script seems to confirm this, but check it anyway. It may help to know what the value of the header exactly looks like).

    The X-Forwarded-For header often includes multiple IP’s. It could be the iTSec plugin is not selecting the correct one (last one, if I’m correct). However if the X-Forwarded-For header only includes the proxy IP then the iTSec plugin can’t help it. In that case you should probably contact Amazone.

    • This reply was modified 2 months, 2 weeks ago by nlpro.
    • This reply was modified 2 months, 2 weeks ago by nlpro.
    • This reply was modified 2 months, 2 weeks ago by nlpro.
    Thread Starter Robert

    (@whi73rav3n)

    Hi @nlpro

    I have checked the X-Forwarded-For header and it does contain the proper IP address of my computer and not the one of the load balancer. It has only one value stored in it, the correct one.

    Thank you!

    Hi @whi73rav3n,

    That is a bit unexpected. When you run the custom script, both the proxy and client IP addresses (in this order), are reported ? Or does that also only produce the client IP address ? Normally I would expect at least 2 IP’s. 1 proxy and 1 client IP, in this order (proxy_IP, client_IP).

    Just to be certain I checked the plugin code and I can confirm it properly selects the last IP when the header contains multiple IP’s.

    Edit: I just noticed your custom script uses the PHP return command which affects the expected outcome. As is, it doesn’t produce any visible output, just returns the first IP. That makes me think, your header value may be in reverse order (client_IP, proxy_IP). Would explain things 😉

    What happens when you change the line below:

    return $ip;

    into:

    echo $ip . '<br />';
    • This reply was modified 2 months, 2 weeks ago by nlpro.
    • This reply was modified 2 months, 2 weeks ago by nlpro.
    • This reply was modified 2 months, 2 weeks ago by nlpro.
    • This reply was modified 2 months, 2 weeks ago by nlpro.
    Thread Starter Robert

    (@whi73rav3n)

    @nlpro The HTTP_X_FORWARDED_FOR key in the $_SERVER variable contains only one IP address, that of my machine, which from the documentation of Cloudfront it is possible.

    What I understand from you is the problem comes from the fact it contains only one value. Am I getting this right?

    Hi @whi73rav3n,

    I can only be certain when you share the result of running your custom script after making the code change as requested in my previous post.

    Even though it is unexpected I don’t think a single IP value is a problem.
    Also, since the proxy IP is used in the plugin, I’m still thinking there is 2 (or even more) IP’s in the header. And they may be listed in reverse order.

    Plugin Support chandelierrr

    (@shanedelierrr)

    Hi @whi73rav3n, thanks for reaching out! I received feedback from our developer regarding the issue. Can you please try enabling the Security Check Pro module and then selecting “Security Check” for the Proxy Detection setting, and see if it helps?

    Thread Starter Robert

    (@whi73rav3n)

    Hello @shanedelierrr

    Found the option for Security Check Pro. Will update ASAP.

    Thank you!

    • This reply was modified 2 months, 2 weeks ago by Robert.
    Thread Starter Robert

    (@whi73rav3n)

    Hi @shanedelierrr

    I am getting the same invalid IP address when running with Security Check Scan as with the other options.

    Hi @whi73rav3n,

    Ok, I’ve done some serious testing with the iTSec plugin build in IP detector. And the result is that it should work properly. It all depends on what IP(s) are (is) in the $_SERVER[‘HTTP_X_FORWARDED_FOR’] variable when the ITSEC_Lib::get_ip() function is first called. Note that this static function can be called multiple times during a WordPress request. So the result of the first call in a request is stored in $GLOBALS[‘__itsec_remote_ip’]. Subsequent calls to the function during the same request simply return the (cached) value as stored in $GLOBALS[‘__itsec_remote_ip’] UNLESS a boolean argument value of false is passed to the function (default value is true).

    Since the iTSec plugin never passes the boolean argument, the first call to the function determins the IP and any subsequent calls during the same request always return the cached value.

    Since the first call to the function is hooked to the WordPress init action, the code below (in the active theme functions.php file) allows us to set the $_SERVER[‘HTTP_X_FORWARDED_FOR’] value to a (by us) controlled value at the right moment:

    add_action('after_setup_theme', 'add_or_edit_xff_value');
    
    function add_or_edit_xff_value(){
    	$_SERVER['HTTP_X_FORWARDED_FOR'] = '1.2.3.4,5.6.7.8';
    }

    You can replace the IP(s) with your actual IP(s). You can also specify a single IP. In the example code 1.2.3.4 is the Proxy IP and 5.6.7.8 is the Client IP. For fun you can also reverse the order …

    With the above code snippet in place AND the PROXY DETECTION setting set to Manual and the PROXY HEADER setting set to X-Forwarded-For the plugin UI will report 5.6.7.8 as the Client IP. In reverse order the plugin UI will report 1.2.3.4 as the Client IP. At least it does so in my test env … Note this post is not a solution, just a way to test things. I hope it helps you figure out what is happening in your env 😉

    Oh I forgot to mention that my testing was done using:

    • PHP 8.0.28
    • WordPress 6.1.1
    • iTSec plugin 8.1.4
    Thread Starter Robert

    (@whi73rav3n)

    @nlpro Thank you for taking the time to investigate this!

    Here is the information on my end after running this piece of code

    Security Check Scan -> IP: 1.2.3.4

    Automatic -> IP: 5.6.7.8

    Manual (X-Forwarded-For) -> IP: 5.6.7.8

    Let me know if you have any thoughts on this.

    Hi @whi73rav3n,

    Ok, so Automatic and Manual (X-Forwarded-For) returns the correct (client) IP.

    But the Security Check Scan value seems to be returning the proxy IP.

    Unfortunately I have no opinion about the Security Check Scan as I have no idea what it does exactly or how it works.

    But the Automatic and Manual(X-Forwarded-For) options seem to be working correctly. It basically confirms the IP detector code works properly when a request includes a X-Forwarded-For header value.

    Why the Security Check Scan returns the proxy IP is a question for the iThemes folks to answer.

    Thread Starter Robert

    (@whi73rav3n)

    Hi @nlpro @shanedelierrr

    When Security Check Pro is enabled the IP detection would work properly if on this line https://plugins.trac.wordpress.org/browser/better-wp-security/trunk/core/lib/class-itsec-ip-detector.php#L123 the code would be

    $parts = preg_split( ‘/[, ]/’, $value, -1, PREG_SPLIT_NO_EMPTY );

    because as it is now an empty value is being added by that preg_split function which should not be there.

    You can test it with this value 1.2.3.4, 5.6.7.8 and see the results.

    I have not yet found a solution for when Security Check Pro is disabled, but the main difference so far is that Security Check Pro adds the X-Forwarded-For header with position 1 and from set to right, while when disabled this header is being added with position -1 and from set to left.

    • This reply was modified 2 months, 2 weeks ago by Robert.
Viewing 15 replies - 1 through 15 (of 30 total)
  • You must be logged in to reply to this topic.