From b9b47768004293f10542cd89cdf94d63caad6caf Mon Sep 17 00:00:00 2001 From: John Blackbourn Date: Thu, 27 Jul 2017 02:24:42 +0000 Subject: [PATCH] Options, Meta APIs: Send a notification to the old admin email address when the site admin email or network admin email address is changed. This reduces the chances of a site compromise going unnoticed, in the same way that the same notifications for user account email address changes reduces the chances of a user account compromise going unnoticed. Props MatheusGimenez, johnbillion Fixes #39117 Built from https://develop.svn.wordpress.org/trunk@41164 git-svn-id: http://core.svn.wordpress.org/trunk@41004 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/includes/admin-filters.php | 1 + wp-admin/includes/ms-admin-filters.php | 3 + wp-includes/functions.php | 82 +++++++++++++++++++++++++ wp-includes/ms-functions.php | 85 ++++++++++++++++++++++++++ wp-includes/version.php | 2 +- 5 files changed, 172 insertions(+), 1 deletion(-) diff --git a/wp-admin/includes/admin-filters.php b/wp-admin/includes/admin-filters.php index 24b42c16fe..240474949c 100644 --- a/wp-admin/includes/admin-filters.php +++ b/wp-admin/includes/admin-filters.php @@ -54,6 +54,7 @@ add_action( 'admin_print_scripts-post-new.php', 'wp_page_reload_on_back_button_j add_action( 'update_option_home', 'update_home_siteurl', 10, 2 ); add_action( 'update_option_siteurl', 'update_home_siteurl', 10, 2 ); add_action( 'update_option_page_on_front', 'update_home_siteurl', 10, 2 ); +add_action( 'update_option_admin_email', 'wp_site_admin_email_change_notification', 10, 3 ); add_filter( 'heartbeat_received', 'wp_check_locked_posts', 10, 3 ); add_filter( 'heartbeat_received', 'wp_refresh_post_lock', 10, 3 ); diff --git a/wp-admin/includes/ms-admin-filters.php b/wp-admin/includes/ms-admin-filters.php index 619ef0963b..20dc77e7c2 100644 --- a/wp-admin/includes/ms-admin-filters.php +++ b/wp-admin/includes/ms-admin-filters.php @@ -22,6 +22,9 @@ add_action( 'update_option_new_admin_email', 'update_option_new_admin_email', 10 // Site Hooks. add_action( 'wpmueditblogaction', 'upload_space_setting' ); +// Network hooks +add_action( 'update_site_option_admin_email', 'wp_network_admin_email_change_notification', 10, 4 ); + // Taxonomy Hooks add_filter( 'get_term', 'sync_category_tag_slugs', 10, 2 ); diff --git a/wp-includes/functions.php b/wp-includes/functions.php index 2b4fe56e16..770e5fe19d 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -5649,3 +5649,85 @@ function wp_cache_get_last_changed( $group ) { return $last_changed; } + +/** + * Send an email to the old site admin email address when the site admin email address changes. + * + * @since 4.9.0 + * + * @param string $old_email The old site admin email address. + * @param string $new_email The new site admin email address. + * @param string $option_name The relevant database option name. + */ +function wp_site_admin_email_change_notification( $old_email, $new_email, $option_name ) { + /** + * Filters whether to send the site admin email change notification email. + * + * @since 4.9.0 + * + * @param bool $send Whether to send the email notification. + * @param string $old_email The old site admin email address. + * @param string $new_email The new site admin email address. + */ + $send = apply_filters( 'send_site_admin_email_change_email', true, $old_email, $new_email ); + + if ( ! $send ) { + return; + } + + /* translators: Do not translate OLD_EMAIL, NEW_EMAIL, SITENAME, SITEURL: those are placeholders. */ + $email_change_text = __( 'Hi, + +This notice confirms that the admin email address was changed on ###SITENAME###. + +The new admin email address is ###NEW_EMAIL###. + +This email has been sent to ###OLD_EMAIL### + +Regards, +All at ###SITENAME### +###SITEURL###' ); + + $email_change_email = array( + 'to' => $old_email, + /* translators: Site admin email change notification email subject. %s: Site title */ + 'subject' => __( '[%s] Notice of Admin Email Change' ), + 'message' => $email_change_text, + 'headers' => '', + ); + // get site name + $site_name = wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ); + + /** + * Filters the contents of the email notification sent when the site admin email address is changed. + * + * @since 4.9.0 + * + * @param array $email_change_email { + * Used to build wp_mail(). + * + * @type string $to The intended recipient. + * @type string $subject The subject of the email. + * @type string $message The content of the email. + * The following strings have a special meaning and will get replaced dynamically: + * - ###OLD_EMAIL### The old site admin email address. + * - ###NEW_EMAIL### The new site admin email address. + * - ###SITENAME### The name of the site. + * - ###SITEURL### The URL to the site. + * @type string $headers Headers. + * } + * @param string $old_email The old site admin email address. + * @param string $new_email The new site admin email address. + */ + $email_change_email = apply_filters( 'site_admin_email_change_email', $email_change_email, $old_email, $new_email ); + + $email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] ); + $email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] ); + $email_change_email['message'] = str_replace( '###SITENAME###', $site_name, $email_change_email['message'] ); + $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] ); + + wp_mail( $email_change_email['to'], sprintf( + $email_change_email['subject'], + $blog_name + ), $email_change_email['message'], $email_change_email['headers'] ); +} diff --git a/wp-includes/ms-functions.php b/wp-includes/ms-functions.php index 3308c07ed0..103955e9b6 100644 --- a/wp-includes/ms-functions.php +++ b/wp-includes/ms-functions.php @@ -2557,3 +2557,88 @@ function get_subdirectory_reserved_names() { */ return apply_filters( 'subdirectory_reserved_names', $names ); } + +/** + * Send an email to the old network admin email address when the network admin email address changes. + * + * @since 4.9.0 + * + * @param string $option_name The relevant database option name. + * @param string $new_email The new network admin email address. + * @param string $old_email The old network admin email address. + * @param int $network_id ID of the network. + */ +function wp_network_admin_email_change_notification( $option_name, $new_email, $old_email, $network_id ) { + /** + * Filters whether to send the network admin email change notification email. + * + * @since 4.9.0 + * + * @param bool $send Whether to send the email notification. + * @param string $old_email The old network admin email address. + * @param string $new_email The new network admin email address. + * @param int $network_id ID of the network. + */ + $send = apply_filters( 'send_network_admin_email_change_email', true, $old_email, $new_email, $network_id ); + + if ( ! $send ) { + return; + } + + /* translators: Do not translate OLD_EMAIL, NEW_EMAIL, SITENAME, SITEURL: those are placeholders. */ + $email_change_text = __( 'Hi, + +This notice confirms that the network admin email address was changed on ###SITENAME###. + +The new network admin email address is ###NEW_EMAIL###. + +This email has been sent to ###OLD_EMAIL### + +Regards, +All at ###SITENAME### +###SITEURL###' ); + + $email_change_email = array( + 'to' => $old_email, + /* translators: Network admin email change notification email subject. %s: Network title */ + 'subject' => __( '[%s] Notice of Network Admin Email Change' ), + 'message' => $email_change_text, + 'headers' => '', + ); + // get network name + $network_name = wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ); + + /** + * Filters the contents of the email notification sent when the network admin email address is changed. + * + * @since 4.9.0 + * + * @param array $email_change_email { + * Used to build wp_mail(). + * + * @type string $to The intended recipient. + * @type string $subject The subject of the email. + * @type string $message The content of the email. + * The following strings have a special meaning and will get replaced dynamically: + * - ###OLD_EMAIL### The old network admin email address. + * - ###NEW_EMAIL### The new network admin email address. + * - ###SITENAME### The name of the network. + * - ###SITEURL### The URL to the site. + * @type string $headers Headers. + * } + * @param string $old_email The old network admin email address. + * @param string $new_email The new network admin email address. + * @param int $network_id ID of the network. + */ + $email_change_email = apply_filters( 'network_admin_email_change_email', $email_change_email, $old_email, $new_email, $network_id ); + + $email_change_email['message'] = str_replace( '###OLD_EMAIL###', $old_email, $email_change_email['message'] ); + $email_change_email['message'] = str_replace( '###NEW_EMAIL###', $new_email, $email_change_email['message'] ); + $email_change_email['message'] = str_replace( '###SITENAME###', $network_name, $email_change_email['message'] ); + $email_change_email['message'] = str_replace( '###SITEURL###', home_url(), $email_change_email['message'] ); + + wp_mail( $email_change_email['to'], sprintf( + $email_change_email['subject'], + $network_name + ), $email_change_email['message'], $email_change_email['headers'] ); +} diff --git a/wp-includes/version.php b/wp-includes/version.php index 399582c558..56395b1dfd 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -4,7 +4,7 @@ * * @global string $wp_version */ -$wp_version = '4.9-alpha-41163'; +$wp_version = '4.9-alpha-41164'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.