| | 7664 | |
| | 7665 | /** |
| | 7666 | * Determines the user's actual IP address and attempts to partially |
| | 7667 | * anonymize an IP address by converting it to a network ID. |
| | 7668 | * |
| | 7669 | * Geolocating the network ID usually returns a similar location as the |
| | 7670 | * actual IP, but provides some privacy for the user. |
| | 7671 | * |
| | 7672 | * $_SERVER['REMOTE_ADDR'] cannot be used in all cases, such as when the user |
| | 7673 | * is making their request through a proxy, or when the web server is behind |
| | 7674 | * a proxy. In those cases, $_SERVER['REMOTE_ADDR'] is set to the proxy address rather |
| | 7675 | * than the user's actual address. |
| | 7676 | * |
| | 7677 | * Modified from https://stackoverflow.com/a/2031935/450127, MIT license. |
| | 7678 | * Modified from https://github.com/geertw/php-ip-anonymizer, MIT license. |
| | 7679 | * |
| | 7680 | * SECURITY WARNING: This function is _NOT_ intended to be used in |
| | 7681 | * circumstances where the authenticity of the IP address matters. This does |
| | 7682 | * _NOT_ guarantee that the returned address is valid or accurate, and it can |
| | 7683 | * be easily spoofed. |
| | 7684 | * |
| | 7685 | * @since 5.6.0 |
| | 7686 | * |
| | 7687 | * @return string|false The anonymized address on success; or false on failure. |
| | 7688 | */ |
| | 7689 | function wp_get_unsafe_client_ip() { |
| | 7690 | $client_ip = false; |
| | 7691 | |
| | 7692 | // In order of preference, with the best ones for this purpose first. |
| | 7693 | $address_headers = array( |
| | 7694 | 'HTTP_CLIENT_IP', |
| | 7695 | 'HTTP_X_FORWARDED_FOR', |
| | 7696 | 'HTTP_X_FORWARDED', |
| | 7697 | 'HTTP_X_CLUSTER_CLIENT_IP', |
| | 7698 | 'HTTP_FORWARDED_FOR', |
| | 7699 | 'HTTP_FORWARDED', |
| | 7700 | 'REMOTE_ADDR', |
| | 7701 | ); |
| | 7702 | |
| | 7703 | foreach ( $address_headers as $header ) { |
| | 7704 | if ( array_key_exists( $header, $_SERVER ) ) { |
| | 7705 | /* |
| | 7706 | * HTTP_X_FORWARDED_FOR can contain a chain of comma-separated |
| | 7707 | * addresses. The first one is the original client. It can't be |
| | 7708 | * trusted for authenticity, but we don't need to for this purpose. |
| | 7709 | */ |
| | 7710 | $address_chain = explode( ',', $_SERVER[ $header ] ); |
| | 7711 | $client_ip = trim( $address_chain[0] ); |
| | 7712 | |
| | 7713 | break; |
| | 7714 | } |
| | 7715 | } |
| | 7716 | |
| | 7717 | if ( ! $client_ip ) { |
| | 7718 | return false; |
| | 7719 | } |
| | 7720 | |
| | 7721 | $anon_ip = wp_privacy_anonymize_ip( $client_ip, true ); |
| | 7722 | |
| | 7723 | if ( '0.0.0.0' === $anon_ip || '::' === $anon_ip ) { |
| | 7724 | return false; |
| | 7725 | } |
| | 7726 | |
| | 7727 | return $anon_ip; |
| | 7728 | } |