Plugin Directory

Changeset 3778544


Ignore:
Timestamp:
11/01/2026 08:51:37 PM (5 hours ago)
Author:
reactwoo
Message:

Update to version 1.9.23 from GitHub

Location:
reactwoo-geocore
Files:
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • reactwoo-geocore/tags/1.9.23/blocks/experience-slot/editor.asset.php

    r3771487 r3778544  
    1717                'wp-i18n',
    1818        ),
    19         'version'      => '1.9.22',
     19        'version'      => '1.9.23',
    2020);
  • reactwoo-geocore/tags/1.9.23/blocks/geo-content/index.asset.php

    r3771487 r3778544  
    1717        ),
    1818        'handle'       => 'rwgc-geo-content-editor',
    19         'version'      => '1.9.22',
     19        'version'      => '1.9.23',
    2020);
  • reactwoo-geocore/tags/1.9.23/includes/class-rwgc-geoip.php

    r3771487 r3778544  
    146146         * is on. Private and loopback addresses are not trusted on their own.
    147147         *
    148          * X-Forwarded-For, Forwarded, X-Real-IP, True-Client-IP, Client-IP,
    149          * CF-Connecting-IP, and CF-IPCountry are ignored for every other peer.
    150          * Behind a trusted proxy, X-Forwarded-For is walked from the right and
    151          * trusted hops are skipped. The left-most value is never taken because it
    152          * is first. CF-Connecting-IP is used only when Behind Cloudflare is on and
    153          * REMOTE_ADDR is inside the bundled Cloudflare ranges.
     148         * X-Forwarded-For, Forwarded, X-Forwarded, X-Real-IP, True-Client-IP,
     149         * Client-IP, CF-Connecting-IP, and CF-IPCountry are ignored for every
     150         * other peer. Behind a trusted proxy, X-Forwarded-For is walked from the
     151         * right and trusted hops are skipped. The left-most value is never taken
     152         * because it is first. X-Real-IP and True-Client-IP are used only when
     153         * that walk has no public hop. Forwarded and X-Forwarded are used only
     154         * when that walk found nothing and the proxy did not send X-Real-IP,
     155         * True-Client-IP, or (while Behind Cloudflare is on) CF-Connecting-IP.
     156         * A present proxy header blocks them even when its value is not a single
     157         * public address, because nginx forwards a client Forwarded header unless
     158         * it is cleared. CF-Connecting-IP is used only when Behind Cloudflare is
     159         * on and REMOTE_ADDR is inside the bundled Cloudflare ranges.
    154160         *
    155161         * `rwgc_is_trusted_proxy` can force the trust decision. `rwgc_visitor_ip`
    … …  
    182188                }
    183189
     190                // Set when the proxy sent a client-address header. Forwarded and
     191                // X-Forwarded stay client-controlled unless that proxy clears them,
     192                // so they must not replace a header the proxy did send.
     193                $proxy_set_client_header = false;
     194
    184195                if ( self::cloudflare_headers_trusted( $remote ) ) {
    185                         $cf = self::first_public_ip( self::server_header( 'HTTP_CF_CONNECTING_IP' ) );
    186                         if ( '' !== $cf && ! self::is_trusted_hop( $cf ) ) {
    187                                 return $cf;
     196                        $cf_raw = self::server_header( 'HTTP_CF_CONNECTING_IP' );
     197                        if ( '' !== $cf_raw ) {
     198                                $proxy_set_client_header = true;
     199                                $cf                      = self::first_public_ip( $cf_raw );
     200                                if ( '' !== $cf && ! self::is_trusted_hop( $cf ) ) {
     201                                        return $cf;
     202                                }
    188203                        }
    189204                }
    … …  
    195210
    196211                foreach ( array( 'HTTP_X_REAL_IP', 'HTTP_TRUE_CLIENT_IP' ) as $key ) {
    197                         $single = self::single_forwarded_ip( self::server_header( $key ) );
     212                        $raw = self::server_header( $key );
     213                        if ( '' === $raw ) {
     214                                continue;
     215                        }
     216                        $proxy_set_client_header = true;
     217                        $single                  = self::single_forwarded_ip( $raw );
    198218                        if ( '' !== $single && ! self::ips_equal( $single, $remote ) && ! self::is_trusted_hop( $single ) ) {
    199219                                return $single;
     220                        }
     221                }
     222
     223                if ( $proxy_set_client_header ) {
     224                        return $remote;
     225                }
     226
     227                foreach ( array( 'HTTP_FORWARDED', 'HTTP_X_FORWARDED' ) as $key ) {
     228                        $from_forwarded = self::visitor_from_forwarding_header( self::server_header( $key ), $remote );
     229                        if ( '' !== $from_forwarded ) {
     230                                return $from_forwarded;
    200231                        }
    201232                }
    … …  
    275306                $out = array();
    276307                foreach ( explode( ',', (string) $header ) as $part ) {
    277                         $ip = trim( $part );
    278                         if ( 0 === stripos( $ip, 'for=' ) ) {
    279                                 $ip = trim( substr( $ip, 4 ), " \t\"[]" );
    280                         }
    281                         $ip = trim( $ip, '[]' );
     308                        $ip = self::ip_token_from_forwarded_part( $part );
    282309                        if ( self::is_public_ip( $ip ) ) {
    283310                                $out[] = $ip;
    … …  
    285312                }
    286313                return $out;
     314        }
     315
     316        /**
     317         * One address from an X-Forwarded-For hop or an RFC 7239 Forwarded element.
     318         *
     319         * `for=` may follow other parameters. A quoted value may be an IPv6 address
     320         * in brackets. Parameters after the address are ignored.
     321         *
     322         * @param string $part Comma-separated element.
     323         * @return string
     324         */
     325        private static function ip_token_from_forwarded_part( $part ) {
     326                $part = trim( (string) $part );
     327                if ( '' === $part ) {
     328                        return '';
     329                }
     330                if ( false !== stripos( $part, 'for=' ) ) {
     331                        if ( ! preg_match( '/(?:^|;)\s*for=\s*("?)(\[[^\]]+\]|[^";,\s]+)\1/i', $part, $matches ) ) {
     332                                return '';
     333                        }
     334                        return trim( $matches[2], " \t\"[]" );
     335                }
     336                return trim( $part, '[]' );
    287337        }
    288338
    … …  
    710760
    711761        /**
    712          * Rightmost public forwarding hop that is not itself a trusted proxy.
    713          *
    714          * Reads X-Forwarded-For, then Forwarded, then X-Forwarded. When every public
    715          * hop is a trusted proxy, the rightmost hop is kept. The left-most address
    716          * is never chosen merely because it is first.
     762         * Rightmost public X-Forwarded-For hop that is not itself a trusted proxy.
     763         *
     764         * When every public hop is a trusted proxy, the rightmost hop is kept.
     765         * The left-most address is never chosen merely because it is first.
     766         * Forwarded and X-Forwarded are not read here; a client can send those
     767         * while the proxy overwrites X-Real-IP.
    717768         *
    718769         * @param string $remote REMOTE_ADDR.
    719          * @return string Empty when the headers have no public hop.
     770         * @return string Empty when the header has no public hop.
    720771         */
    721772        private static function visitor_from_trusted_xff( $remote ) {
    722                 $ips = self::public_ips_from_header( self::server_header( 'HTTP_X_FORWARDED_FOR' ) );
    723                 if ( empty( $ips ) ) {
    724                         $ips = self::public_ips_from_header( self::server_header( 'HTTP_FORWARDED' ) );
    725                 }
    726                 if ( empty( $ips ) ) {
    727                         $ips = self::public_ips_from_header( self::server_header( 'HTTP_X_FORWARDED' ) );
    728                 }
     773                return self::visitor_from_forwarding_header( self::server_header( 'HTTP_X_FORWARDED_FOR' ), $remote );
     774        }
     775
     776        /**
     777         * Rightmost public hop in one forwarding header that is not a trusted proxy.
     778         *
     779         * @param string $header Header value.
     780         * @param string $remote REMOTE_ADDR.
     781         * @return string Empty when the header has no public hop.
     782         */
     783        private static function visitor_from_forwarding_header( $header, $remote ) {
     784                $ips   = self::public_ips_from_header( $header );
    729785                $count = count( $ips );
    730786                if ( 0 === $count ) {
  • reactwoo-geocore/tags/1.9.23/reactwoo-geocore.php

    r3771487 r3778544  
    44 * Plugin URI: https://reactwoo.com/geo-core/
    55 * Description: Country-targeted content for your website. MaxMind country detection, shortcodes, a Gutenberg block, REST, and country visibility rules. No ReactWoo product license is required for those features.
    6  * Version: 1.9.22
     6 * Version: 1.9.23
    77 * Requires at least: 6.2
    88 * Requires PHP: 8.1
    … …  
    2020// Core constants.
    2121if ( ! defined( 'RWGC_VERSION' ) ) {
    22         define( 'RWGC_VERSION', '1.9.22' );
     22        define( 'RWGC_VERSION', '1.9.23' );
    2323}
    2424if ( ! defined( 'RWGC_FILE' ) ) {
  • reactwoo-geocore/tags/1.9.23/readme.txt

    r3771487 r3778544  
    55Tested up to: 7.1
    66Requires PHP: 8.1
    7 Stable tag: 1.9.22
     7Stable tag: 1.9.23
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    165165
    166166Recent releases are listed here. Older notes: https://github.com/reactwoo/reactwoo-geocore/blob/main/CHANGELOG.md and the history of this file on GitHub.
     167
     168= 1.9.23 =
     169* A visitor can no longer choose a country by sending a Forwarded or X-Forwarded header when the proxy has set X-Real-IP or True-Client-IP. That stays true when the proxy header is present but is not a single public address. Cloudflare's CF-Connecting-IP is not replaced by those headers while Behind Cloudflare is on.
    167170
    168171= 1.9.22 =
    … …  
    318321== Upgrade Notice ==
    319322
     323= 1.9.23 =
     324A client Forwarded or X-Forwarded header no longer replaces the visitor address a trusted proxy set in X-Real-IP or True-Client-IP. Trusted proxies and Behind Cloudflare are unchanged from 1.9.22.
     325
    320326= 1.9.22 =
    321327Visitor country is taken from the connection address unless you list a trusted proxy or turn on Behind Cloudflare. Sites that already use Cloudflare keep that behaviour until settings are saved. Review Settings → Detection after updating.
  • reactwoo-geocore/tags/1.9.23/vendor/composer/installed.php

    r3771487 r3778544  
    22    'root' => array(
    33        'name' => 'reactwoo/reactwoo-geocore',
    4         'pretty_version' => 'v1.9.22',
    5         'version' => '1.9.22.0',
    6         'reference' => '9f185d5845b72dd9904405ca456b8fa0a9a048c4',
     4        'pretty_version' => 'v1.9.23',
     5        'version' => '1.9.23.0',
     6        'reference' => 'c8b38ce5625d2ebf6131974846af8b92b2665400',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    4848        ),
    4949        'reactwoo/reactwoo-geocore' => array(
    50             'pretty_version' => 'v1.9.22',
    51             'version' => '1.9.22.0',
    52             'reference' => '9f185d5845b72dd9904405ca456b8fa0a9a048c4',
     50            'pretty_version' => 'v1.9.23',
     51            'version' => '1.9.23.0',
     52            'reference' => 'c8b38ce5625d2ebf6131974846af8b92b2665400',
    5353            'type' => 'wordpress-plugin',
    5454            'install_path' => __DIR__ . '/../../',
  • reactwoo-geocore/trunk/blocks/experience-slot/editor.asset.php

    r3771487 r3778544  
    1717                'wp-i18n',
    1818        ),
    19         'version'      => '1.9.22',
     19        'version'      => '1.9.23',
    2020);
  • reactwoo-geocore/trunk/blocks/geo-content/index.asset.php

    r3771487 r3778544  
    1717        ),
    1818        'handle'       => 'rwgc-geo-content-editor',
    19         'version'      => '1.9.22',
     19        'version'      => '1.9.23',
    2020);
  • reactwoo-geocore/trunk/includes/class-rwgc-geoip.php

    r3771487 r3778544  
    146146         * is on. Private and loopback addresses are not trusted on their own.
    147147         *
    148          * X-Forwarded-For, Forwarded, X-Real-IP, True-Client-IP, Client-IP,
    149          * CF-Connecting-IP, and CF-IPCountry are ignored for every other peer.
    150          * Behind a trusted proxy, X-Forwarded-For is walked from the right and
    151          * trusted hops are skipped. The left-most value is never taken because it
    152          * is first. CF-Connecting-IP is used only when Behind Cloudflare is on and
    153          * REMOTE_ADDR is inside the bundled Cloudflare ranges.
     148         * X-Forwarded-For, Forwarded, X-Forwarded, X-Real-IP, True-Client-IP,
     149         * Client-IP, CF-Connecting-IP, and CF-IPCountry are ignored for every
     150         * other peer. Behind a trusted proxy, X-Forwarded-For is walked from the
     151         * right and trusted hops are skipped. The left-most value is never taken
     152         * because it is first. X-Real-IP and True-Client-IP are used only when
     153         * that walk has no public hop. Forwarded and X-Forwarded are used only
     154         * when that walk found nothing and the proxy did not send X-Real-IP,
     155         * True-Client-IP, or (while Behind Cloudflare is on) CF-Connecting-IP.
     156         * A present proxy header blocks them even when its value is not a single
     157         * public address, because nginx forwards a client Forwarded header unless
     158         * it is cleared. CF-Connecting-IP is used only when Behind Cloudflare is
     159         * on and REMOTE_ADDR is inside the bundled Cloudflare ranges.
    154160         *
    155161         * `rwgc_is_trusted_proxy` can force the trust decision. `rwgc_visitor_ip`
    … …  
    182188                }
    183189
     190                // Set when the proxy sent a client-address header. Forwarded and
     191                // X-Forwarded stay client-controlled unless that proxy clears them,
     192                // so they must not replace a header the proxy did send.
     193                $proxy_set_client_header = false;
     194
    184195                if ( self::cloudflare_headers_trusted( $remote ) ) {
    185                         $cf = self::first_public_ip( self::server_header( 'HTTP_CF_CONNECTING_IP' ) );
    186                         if ( '' !== $cf && ! self::is_trusted_hop( $cf ) ) {
    187                                 return $cf;
     196                        $cf_raw = self::server_header( 'HTTP_CF_CONNECTING_IP' );
     197                        if ( '' !== $cf_raw ) {
     198                                $proxy_set_client_header = true;
     199                                $cf                      = self::first_public_ip( $cf_raw );
     200                                if ( '' !== $cf && ! self::is_trusted_hop( $cf ) ) {
     201                                        return $cf;
     202                                }
    188203                        }
    189204                }
    … …  
    195210
    196211                foreach ( array( 'HTTP_X_REAL_IP', 'HTTP_TRUE_CLIENT_IP' ) as $key ) {
    197                         $single = self::single_forwarded_ip( self::server_header( $key ) );
     212                        $raw = self::server_header( $key );
     213                        if ( '' === $raw ) {
     214                                continue;
     215                        }
     216                        $proxy_set_client_header = true;
     217                        $single                  = self::single_forwarded_ip( $raw );
    198218                        if ( '' !== $single && ! self::ips_equal( $single, $remote ) && ! self::is_trusted_hop( $single ) ) {
    199219                                return $single;
     220                        }
     221                }
     222
     223                if ( $proxy_set_client_header ) {
     224                        return $remote;
     225                }
     226
     227                foreach ( array( 'HTTP_FORWARDED', 'HTTP_X_FORWARDED' ) as $key ) {
     228                        $from_forwarded = self::visitor_from_forwarding_header( self::server_header( $key ), $remote );
     229                        if ( '' !== $from_forwarded ) {
     230                                return $from_forwarded;
    200231                        }
    201232                }
    … …  
    275306                $out = array();
    276307                foreach ( explode( ',', (string) $header ) as $part ) {
    277                         $ip = trim( $part );
    278                         if ( 0 === stripos( $ip, 'for=' ) ) {
    279                                 $ip = trim( substr( $ip, 4 ), " \t\"[]" );
    280                         }
    281                         $ip = trim( $ip, '[]' );
     308                        $ip = self::ip_token_from_forwarded_part( $part );
    282309                        if ( self::is_public_ip( $ip ) ) {
    283310                                $out[] = $ip;
    … …  
    285312                }
    286313                return $out;
     314        }
     315
     316        /**
     317         * One address from an X-Forwarded-For hop or an RFC 7239 Forwarded element.
     318         *
     319         * `for=` may follow other parameters. A quoted value may be an IPv6 address
     320         * in brackets. Parameters after the address are ignored.
     321         *
     322         * @param string $part Comma-separated element.
     323         * @return string
     324         */
     325        private static function ip_token_from_forwarded_part( $part ) {
     326                $part = trim( (string) $part );
     327                if ( '' === $part ) {
     328                        return '';
     329                }
     330                if ( false !== stripos( $part, 'for=' ) ) {
     331                        if ( ! preg_match( '/(?:^|;)\s*for=\s*("?)(\[[^\]]+\]|[^";,\s]+)\1/i', $part, $matches ) ) {
     332                                return '';
     333                        }
     334                        return trim( $matches[2], " \t\"[]" );
     335                }
     336                return trim( $part, '[]' );
    287337        }
    288338
    … …  
    710760
    711761        /**
    712          * Rightmost public forwarding hop that is not itself a trusted proxy.
    713          *
    714          * Reads X-Forwarded-For, then Forwarded, then X-Forwarded. When every public
    715          * hop is a trusted proxy, the rightmost hop is kept. The left-most address
    716          * is never chosen merely because it is first.
     762         * Rightmost public X-Forwarded-For hop that is not itself a trusted proxy.
     763         *
     764         * When every public hop is a trusted proxy, the rightmost hop is kept.
     765         * The left-most address is never chosen merely because it is first.
     766         * Forwarded and X-Forwarded are not read here; a client can send those
     767         * while the proxy overwrites X-Real-IP.
    717768         *
    718769         * @param string $remote REMOTE_ADDR.
    719          * @return string Empty when the headers have no public hop.
     770         * @return string Empty when the header has no public hop.
    720771         */
    721772        private static function visitor_from_trusted_xff( $remote ) {
    722                 $ips = self::public_ips_from_header( self::server_header( 'HTTP_X_FORWARDED_FOR' ) );
    723                 if ( empty( $ips ) ) {
    724                         $ips = self::public_ips_from_header( self::server_header( 'HTTP_FORWARDED' ) );
    725                 }
    726                 if ( empty( $ips ) ) {
    727                         $ips = self::public_ips_from_header( self::server_header( 'HTTP_X_FORWARDED' ) );
    728                 }
     773                return self::visitor_from_forwarding_header( self::server_header( 'HTTP_X_FORWARDED_FOR' ), $remote );
     774        }
     775
     776        /**
     777         * Rightmost public hop in one forwarding header that is not a trusted proxy.
     778         *
     779         * @param string $header Header value.
     780         * @param string $remote REMOTE_ADDR.
     781         * @return string Empty when the header has no public hop.
     782         */
     783        private static function visitor_from_forwarding_header( $header, $remote ) {
     784                $ips   = self::public_ips_from_header( $header );
    729785                $count = count( $ips );
    730786                if ( 0 === $count ) {
  • reactwoo-geocore/trunk/reactwoo-geocore.php

    r3771487 r3778544  
    44 * Plugin URI: https://reactwoo.com/geo-core/
    55 * Description: Country-targeted content for your website. MaxMind country detection, shortcodes, a Gutenberg block, REST, and country visibility rules. No ReactWoo product license is required for those features.
    6  * Version: 1.9.22
     6 * Version: 1.9.23
    77 * Requires at least: 6.2
    88 * Requires PHP: 8.1
    … …  
    2020// Core constants.
    2121if ( ! defined( 'RWGC_VERSION' ) ) {
    22         define( 'RWGC_VERSION', '1.9.22' );
     22        define( 'RWGC_VERSION', '1.9.23' );
    2323}
    2424if ( ! defined( 'RWGC_FILE' ) ) {
  • reactwoo-geocore/trunk/readme.txt

    r3771487 r3778544  
    55Tested up to: 7.1
    66Requires PHP: 8.1
    7 Stable tag: 1.9.22
     7Stable tag: 1.9.23
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    165165
    166166Recent releases are listed here. Older notes: https://github.com/reactwoo/reactwoo-geocore/blob/main/CHANGELOG.md and the history of this file on GitHub.
     167
     168= 1.9.23 =
     169* A visitor can no longer choose a country by sending a Forwarded or X-Forwarded header when the proxy has set X-Real-IP or True-Client-IP. That stays true when the proxy header is present but is not a single public address. Cloudflare's CF-Connecting-IP is not replaced by those headers while Behind Cloudflare is on.
    167170
    168171= 1.9.22 =
    … …  
    318321== Upgrade Notice ==
    319322
     323= 1.9.23 =
     324A client Forwarded or X-Forwarded header no longer replaces the visitor address a trusted proxy set in X-Real-IP or True-Client-IP. Trusted proxies and Behind Cloudflare are unchanged from 1.9.22.
     325
    320326= 1.9.22 =
    321327Visitor country is taken from the connection address unless you list a trusted proxy or turn on Behind Cloudflare. Sites that already use Cloudflare keep that behaviour until settings are saved. Review Settings → Detection after updating.
  • reactwoo-geocore/trunk/vendor/composer/installed.php

    r3771487 r3778544  
    22    'root' => array(
    33        'name' => 'reactwoo/reactwoo-geocore',
    4         'pretty_version' => 'v1.9.22',
    5         'version' => '1.9.22.0',
    6         'reference' => '9f185d5845b72dd9904405ca456b8fa0a9a048c4',
     4        'pretty_version' => 'v1.9.23',
     5        'version' => '1.9.23.0',
     6        'reference' => 'c8b38ce5625d2ebf6131974846af8b92b2665400',
    77        'type' => 'wordpress-plugin',
    88        'install_path' => __DIR__ . '/../../',
    … …  
    4848        ),
    4949        'reactwoo/reactwoo-geocore' => array(
    50             'pretty_version' => 'v1.9.22',
    51             'version' => '1.9.22.0',
    52             'reference' => '9f185d5845b72dd9904405ca456b8fa0a9a048c4',
     50            'pretty_version' => 'v1.9.23',
     51            'version' => '1.9.23.0',
     52            'reference' => 'c8b38ce5625d2ebf6131974846af8b92b2665400',
    5353            'type' => 'wordpress-plugin',
    5454            'install_path' => __DIR__ . '/../../',
Note: See TracChangeset for help on using the changeset viewer.