Make WordPress Core


Ignore:
Timestamp:
05/02/2018 12:48:23 AM (8 years ago)
Author:
SergeyBiryukov
Message:

Privacy: add helper function for anonymizing data in a standardized way.

Props jesperher, allendav, iandunn, birgire, azaozz, joemcgill.
Merges [42971] and [43081] to the 4.9 branch.
Fixes #43545.

Location:
branches/4.9
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/4.9

  • branches/4.9/src/wp-includes/functions.php

    r42811 r43082  
    58175817        ), $email_change_email['message'], $email_change_email['headers'] );
    58185818}
     5819
     5820/**
     5821 * Return an anonymized IPv4 or IPv6 address.
     5822 *
     5823 * @since 4.9.6 Abstracted from `WP_Community_Events::get_unsafe_client_ip()`.
     5824 *
     5825 * @param  string $ip_addr        The IPv4 or IPv6 address to be anonymized.
     5826 * @param  bool   $ipv6_fallback  Optional. Whether to return the original IPv6 address if the needed functions
     5827 *                                to anonymize it are not present. Default false, return `::` (unspecified address).
     5828 * @return string  The anonymized IP address.
     5829 */
     5830function wp_privacy_anonymize_ip( $ip_addr, $ipv6_fallback = false ) {
     5831        // Detect what kind of IP address this is.
     5832        $ip_prefix = '';
     5833        $is_ipv6   = substr_count( $ip_addr, ':' ) > 1;
     5834        $is_ipv4   = ( 3 === substr_count( $ip_addr, '.' ) );
     5835
     5836        if ( $is_ipv6 && $is_ipv4 ) {
     5837                // IPv6 compatibility mode, temporarily strip the IPv6 part, and treat it like IPv4.
     5838                $ip_prefix = '::ffff:';
     5839                $ip_addr   = preg_replace( '/^\[?[0-9a-f:]*:/i', '', $ip_addr );
     5840                $ip_addr   = str_replace( ']', '', $ip_addr );
     5841                $is_ipv6   = false;
     5842        }
     5843
     5844        if ( $is_ipv6 ) {
     5845                // IPv6 addresses will always be enclosed in [] if there's a port.
     5846                $left_bracket  = strpos( $ip_addr, '[' );
     5847                $right_bracket = strpos( $ip_addr, ']' );
     5848                $percent       = strpos( $ip_addr, '%' );
     5849                $netmask       = 'ffff:ffff:ffff:ffff:0000:0000:0000:0000';
     5850
     5851                // Strip the port (and [] from IPv6 addresses), if they exist.
     5852                if ( false !== $left_bracket && false !== $right_bracket ) {
     5853                        $ip_addr = substr( $ip_addr, $left_bracket + 1, $right_bracket - $left_bracket - 1 );
     5854                } elseif ( false !== $left_bracket || false !== $right_bracket ) {
     5855                        // The IP has one bracket, but not both, so it's malformed.
     5856                        return '::';
     5857                }
     5858
     5859                // Strip the reachability scope.
     5860                if ( false !== $percent ) {
     5861                        $ip_addr = substr( $ip_addr, 0, $percent );
     5862                }
     5863
     5864                // No invalid characters should be left.
     5865                if ( preg_match( '/[^0-9a-f:]/i', $ip_addr ) ) {
     5866                        return '::';
     5867                }
     5868
     5869                // Partially anonymize the IP by reducing it to the corresponding network ID.
     5870                if ( function_exists( 'inet_pton' ) && function_exists( 'inet_ntop' ) ) {
     5871                        $ip_addr = inet_ntop( inet_pton( $ip_addr ) & inet_pton( $netmask ) );
     5872                        if ( false === $ip_addr) {
     5873                                return '::';
     5874                        }
     5875                } elseif ( ! $ipv6_fallback ) {
     5876                        return '::';
     5877                }
     5878        } elseif ( $is_ipv4 ) {
     5879                // Strip any port and partially anonymize the IP.
     5880                $last_octet_position = strrpos( $ip_addr, '.' );
     5881                $ip_addr             = substr( $ip_addr, 0, $last_octet_position ) . '.0';
     5882        } else {
     5883                return '0.0.0.0';
     5884        }
     5885
     5886        // Restore the IPv6 prefix to compatibility mode addresses.
     5887        return $ip_prefix . $ip_addr;
     5888}
     5889
     5890/**
     5891 * Return uniform "anonymous" data by type.
     5892 *
     5893 * @since 4.9.6
     5894 *
     5895 * @param  string $type The type of data to be anonymized.
     5896 * @param  string $data Optional The data to be anonymized.
     5897 * @return string The anonymous data for the requested type.
     5898 */
     5899function wp_privacy_anonymize_data( $type, $data = '' ) {
     5900
     5901        switch ( $type ) {
     5902                case 'email':
     5903                        $anonymous = 'deleted@site.invalid';
     5904                        break;
     5905                case 'url':
     5906                        $anonymous = 'https://site.invalid';
     5907                        break;
     5908                case 'ip':
     5909                        $anonymous = wp_privacy_anonymize_ip( $data );
     5910                        break;
     5911                case 'date':
     5912                        $anonymous = '0000-00-00 00:00:00';
     5913                        break;
     5914                case 'text':
     5915                        /* translators: deleted text */
     5916                        $anonymous = __( '[deleted]' );
     5917                        break;
     5918                case 'longtext':
     5919                        /* translators: deleted long text */
     5920                        $anonymous = __( 'This content was deleted by the author.' );
     5921                        break;
     5922                default:
     5923                        $anonymous = '';
     5924        }
     5925
     5926        /**
     5927         * Filters the anonymous data for each type.
     5928         *
     5929         * @since 4.9.6
     5930         *
     5931         * @param string $anonymous Anonymized data.
     5932         * @param string $type      Type of the data.
     5933         * @param string $data      Original data.
     5934         */
     5935        return apply_filters( 'wp_privacy_anonymize_data', $anonymous, $type, $data );
     5936}
Note: See TracChangeset for help on using the changeset viewer.