Make WordPress Core

Changeset 32820


Ignore:
Timestamp:
06/17/2015 07:30:37 PM (9 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.