WordPress.org

Make WordPress Core

Changeset 32820


Ignore:
Timestamp:
06/17/15 19:30:37 (3 years ago)
Author:
markjaquith
Message:

Send emails when a user's email address or password is changed.

  • In case of email change, email goes to the OLD address
  • Prevents against issues where an account is compromised (say via cookie interception) and then the attacker silently takes over ownership via pw/email changes — now there will at least be a record that something is up

fixes #32430
props RMarks, MikeHansenMe, tharsheblows, obenland

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/user.php

    r32713 r32820  
    21412141    $user = add_magic_quotes( $user ); 
    21422142 
    2143     // If password is changing, hash it now. 
    21442143    if ( ! empty($userdata['user_pass']) ) { 
     2144        // If password is changing, hash it now 
    21452145        $plaintext_pass = $userdata['user_pass']; 
    2146         $userdata['user_pass'] = wp_hash_password($userdata['user_pass']); 
    2147     } 
    2148  
    2149     wp_cache_delete($user[ 'user_email' ], 'useremail'); 
     2146        $userdata['user_pass'] = wp_hash_password( $userdata['user_pass'] ); 
     2147        /** 
     2148         * Filter to stop the sending of the password change email. 
     2149         * 
     2150         * @since 4.3 
     2151         * @see  wp_insert_user() For $user and $userdata fields. 
     2152         * 
     2153         * @param bool Return false to not send the email. 
     2154         * @param array $user The original user array. 
     2155         * @param array $userdata The updated user array. 
     2156         * 
     2157         */ 
     2158        $send_pass_change_email = apply_filters( 'send_pass_change_email', true, $user, $userdata ); 
     2159    } 
     2160 
     2161    if ( $user['user_email'] !== $userdata['user_email'] ) { 
     2162        /** 
     2163         * Filter to stop the sending of the email change email. 
     2164         * 
     2165         * @since 4.3 
     2166         * @see  wp_insert_user() For $user and $userdata fields. 
     2167         * 
     2168         * @param bool Return false to not send the email. 
     2169         * @param array $user The original user array. 
     2170         * @param array $userdata The updated user array. 
     2171         * 
     2172         */ 
     2173        $send_email_change_email = apply_filters( 'send_email_change_email', true, $user, $userdata ); 
     2174    } 
     2175 
     2176    wp_cache_delete( $user['user_email'], 'useremail' ); 
    21502177 
    21512178    // Merge old and new fields with new fields overwriting old ones. 
    2152     $userdata = array_merge($user, $userdata); 
    2153     $user_id = wp_insert_user($userdata); 
     2179    $userdata = array_merge( $user, $userdata ); 
     2180    $user_id = wp_insert_user( $userdata ); 
     2181 
     2182    if ( ! is_wp_error( $user_id ) ) { 
     2183 
     2184        $blog_name = wp_specialchars_decode( get_option( 'blogname' ) ); 
     2185 
     2186        if ( ! empty( $send_pass_change_email ) ) { 
     2187 
     2188            /* translators: Do not translate USERNAME, ADMIN_EMAIL, EMAIL, SITENAME, SITEURL: those are placeholders. */ 
     2189            $pass_change_text = __( 'Hi ###USERNAME###, 
     2190 
     2191This notice confirms that your password was changed on ###SITENAME###. 
     2192 
     2193If you did not change your password, please contact the Site Administrator at 
     2194###ADMIN_EMAIL### 
     2195 
     2196This email has been sent to ###EMAIL### 
     2197 
     2198Regards, 
     2199All at ###SITENAME### 
     2200###SITEURL###' ); 
     2201 
     2202            $pass_change_email = array( 
     2203                'to'      => $user['user_email'], 
     2204                'subject' => __( '[%s] Notice of Password Change' ), 
     2205                'message' => $pass_change_text, 
     2206                'headers' => '', 
     2207            ); 
     2208 
     2209            /** 
     2210             * Filter the email sent when the user's password is changed. 
     2211             * 
     2212             * @since 4.3 
     2213             * 
     2214             * @param array $pass_change_email { 
     2215             *            Used to build wp_mail(). https://developer.wordpress.org/reference/functions/wp_mail/ 
     2216             *            @type string $to      The intended recipients. Add emails in a comma separated string. 
     2217             *            @type string $subject The subject of the email. 
     2218             *            @type string $message The content of the email. 
     2219             *                The following strings have a special meaning and will get replaced dynamically: 
     2220             *                ###USERNAME###    The current user's username. 
     2221             *                ###ADMIN_EMAIL### The admin email in case this was unexpected. 
     2222             *                ###EMAIL###       The old email. 
     2223             *                ###SITENAME###    The name of the site. 
     2224             *                ###SITEURL###     The URL to the site. 
     2225             *            @type  string $headers Headers. Add headers in a newline (\r\n) separated string. 
     2226             *        } 
     2227             * @param array $user The original user array. 
     2228             * @param array $userdata The updated user array. 
     2229             * 
     2230             */ 
     2231            $pass_change_email = apply_filters( 'password_change_email', $pass_change_email, $user, $userdata ); 
     2232 
     2233            $pass_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $pass_change_email['message'] ); 
     2234            $pass_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $pass_change_email['message'] ); 
     2235            $pass_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $pass_change_email['message'] ); 
     2236            $pass_change_email['message'] = str_replace( '###SITENAME###', get_option( 'blogname' ), $pass_change_email['message'] ); 
     2237            $pass_change_email['message'] = str_replace( '###SITEURL###', get_option( 'siteurl' ), $pass_change_email['message'] ); 
     2238 
     2239            wp_mail( $pass_change_email['to'], sprintf( $pass_change_email['subject'], $blog_name ), $pass_change_email['message'], $pass_change_email['headers'] ); 
     2240        } 
     2241 
     2242        if ( ! empty( $send_email_change_email ) ) { 
     2243            /* translators: Do not translate USERNAME, ADMIN_EMAIL, EMAIL, SITENAME, SITEURL: those are placeholders. */ 
     2244            $email_change_text = __( 'Hi ###USERNAME###, 
     2245 
     2246This notice confirms that your email was changed on ###SITENAME###. 
     2247 
     2248If you did not change your email, please contact the Site Administrator at 
     2249###ADMIN_EMAIL### 
     2250 
     2251This email has been sent to ###EMAIL### 
     2252 
     2253Regards, 
     2254All at ###SITENAME### 
     2255###SITEURL###' ); 
     2256 
     2257            $email_change_email = array( 
     2258                'to'      => $user['user_email'], 
     2259                'subject' => __( '[%s] Notice of Email Change' ), 
     2260                'message' => $email_change_text, 
     2261                'headers' => '', 
     2262            ); 
     2263 
     2264            /** 
     2265             * Filter the email sent when the user's password is changed. 
     2266             * 
     2267             * @since 4.3 
     2268             * 
     2269             * @param array $email_change_email { 
     2270             *            Used to build wp_mail(). https://developer.wordpress.org/reference/functions/wp_mail/ 
     2271             *            @type string $to      The intended recipients. 
     2272             *            @type string $subject The subject of the email. 
     2273             *            @type string $message The content of the email. 
     2274             *                The following strings have a special meaning and will get replaced dynamically: 
     2275             *                ###USERNAME###    The current user's username. 
     2276             *                ###ADMIN_EMAIL### The admin email in case this was unexpected. 
     2277             *                ###EMAIL###       The old email. 
     2278             *                ###SITENAME###    The name of the site. 
     2279             *                ###SITEURL###     The URL to the site. 
     2280             *            @type string $headers Headers. 
     2281             *        } 
     2282             * @param array $user The original user array. 
     2283             * @param array $userdata The updated user array. 
     2284             */ 
     2285            $email_change_email = apply_filters( 'email_change_email', $email_change_email, $user, $userdata ); 
     2286 
     2287            $email_change_email['message'] = str_replace( '###USERNAME###', $user['user_login'], $email_change_email['message'] ); 
     2288            $email_change_email['message'] = str_replace( '###ADMIN_EMAIL###', get_option( 'admin_email' ), $email_change_email['message'] ); 
     2289            $email_change_email['message'] = str_replace( '###EMAIL###', $user['user_email'], $email_change_email['message'] ); 
     2290            $email_change_email['message'] = str_replace( '###SITENAME###', get_option( 'blogname' ), $email_change_email['message'] ); 
     2291            $email_change_email['message'] = str_replace( '###SITEURL###', get_option( 'siteurl' ), $email_change_email['message'] ); 
     2292 
     2293            wp_mail( $email_change_email['to'], sprintf( $email_change_email['subject'], $blog_name ), $email_change_email['message'], $email_change_email['headers'] ); 
     2294        } 
     2295    } 
    21542296 
    21552297    // Update the cookies if the password changed. 
Note: See TracChangeset for help on using the changeset viewer.