WordPress.org

Make WordPress Core

Ticket #41083: 41083.1.diff

File 41083.1.diff, 3.2 KB (added by iandunn, 2 years ago)

Alternate approach with tests - not finished

  • src/wp-admin/includes/class-wp-community-events.php

    diff --git src/wp-admin/includes/class-wp-community-events.php src/wp-admin/includes/class-wp-community-events.php
    index 211d37ea5e..c075bbcfec 100644
    class WP_Community_Events { 
    236236         *                      or false on failure.
    237237         */
    238238        public static function get_unsafe_client_ip() {
    239                 $client_ip = false;
     239                $client_ip = $netmask = false;
    240240
    241241                // In order of preference, with the best ones for this purpose first.
    242242                $address_headers = array(
    class WP_Community_Events { 
    263263                        }
    264264                }
    265265
    266                 // These functions are not available on Windows until PHP 5.3.
    267                 if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
    268                         if ( 4 === strlen( inet_pton( $client_ip ) ) ) {
    269                                 $netmask = '255.255.255.0'; // ipv4.
    270                         } else {
    271                                 $netmask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000'; // ipv6.
     266                /*
     267                 * The filter extension is enabled by default, but some configurations
     268                 * disable it. Skipping this has the effect of disabling the IP geolocation,
     269                 * but the user can still manually enter their location, so it's an acceptable
     270                 * fallback.
     271                 */
     272                if ( $client_ip && function_exists( 'filter_var' ) ) {
     273                        if ( filter_var( $client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 ) ) {
     274                                $ip_parts  = explode( ':', $client_ip );
     275                                $client_ip = $ip_parts[0];
     276                                $netmask   = '255.255.255.0';
     277                        } elseif ( filter_var( $client_ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 ) ) {
     278                                // todo - $client_ip = $client_ip with ports stripped off
     279                                $netmask = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000';
    272280                        }
     281                }
    273282
     283                // These functions are not available on Windows until PHP 5.3.
     284                if ( $client_ip && $netmask && function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
    274285                        $client_ip = inet_ntop( inet_pton( $client_ip ) & inet_pton( $netmask ) );
    275286                }
    276287
  • tests/phpunit/tests/admin/includesCommunityEvents.php

    diff --git tests/phpunit/tests/admin/includesCommunityEvents.php tests/phpunit/tests/admin/includesCommunityEvents.php
    index ed5cc2caee..c0acefce67 100644
    class Test_WP_Community_Events extends WP_UnitTestCase { 
    255255                        'filename' => '',
    256256                );
    257257        }
     258
     259        /**
     260         * Test that get_unsafe_client_ip() properly anonymizes all possible address formats
     261         *
     262         * @ticket 41083
     263         * @since 4.8.1
     264         */
     265        public function test_get_unsafe_client_ip_anonymization() {
     266                $test_cases = array(
     267                        '127.0.0.1'                    => '127.0.0.0',              // Local IPv4
     268                        '104.205.87.98'                => '104.205.87.0',           // Public IPv4
     269                        '104.205.87.98:58749'          => '104.205.87.0',           // IPv4 with port
     270                        '1fff:0:a88:85a3::ac1f'        => '1fff:0:a88:85a3::ac1f',  // IPv6
     271                        '[1fff:0:a88:85a3::ac1f]:8001' => '1fff:0:a88:85a3::ac1f',  // IPv6 with port
     272                        // todo - add test cases from https://github.com/geertw/php-ip-anonymizer
     273                );
     274
     275                foreach ( $test_cases as $raw_ip => $expected_result ) {
     276                        $_GET['REMOTE_ADDR'] = $raw_ip;
     277                        $actual_result       = WP_Community_Events::get_unsafe_client_ip();
     278
     279                        $this->assertEquals( $expected_result, $actual_result );
     280                }
     281        }
    258282}