Security, Site Health: Improve accuracy in messaging about HTTPS support.

Following up on [49904], this changeset focuses mainly on improving the guidance about the current state of HTTPS in Site Health.

* Correct the existing copy to indicate that both the Site Address and the WordPress Address need to be changed to fully switch to HTTPS.
* Link to the respective input fields via anchor links rather than to the overall General Settings screen.
* Show different copy if the site is using HTTPS for the WordPress Address (for example to have only the administration panel in HTTPS), but not for the Site Address.
* Inform the user about potential problems even when the site is already using HTTPS, for example if the SSL certificate was no longer valid.
* Always rely on fresh information for determining HTTPS support issues in Site Health, and therefore change the `https_status` test to become asynchronous.
* Rename the new private `wp_is_owned_html_output()` function to a more appropriate `wp_is_local_html_output()`.

Props adamsilverstein, flixos90, johnjamesjacoby, timothyblynjacobs.
See #47577.

Built from https://develop.svn.wordpress.org/trunk@50072


git-svn-id: http://core.svn.wordpress.org/trunk@49773 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Felix Arntz 2021-01-29 19:10:58 +00:00
parent ae40aad4c0
commit 9d348e26f3
4 changed files with 152 additions and 34 deletions

View File

@ -108,7 +108,7 @@ class WP_Site_Health {
// Don't run https test on development environments.
if ( $this->is_development_environment() ) {
unset( $tests['direct']['https_status'] );
unset( $tests['async']['https_status'] );
}
foreach ( $tests['direct'] as $test ) {
@ -1498,6 +1498,10 @@ class WP_Site_Health {
* @return array The test results.
*/
public function get_test_https_status() {
// Enforce fresh HTTPS detection results. This is normally invoked by using cron, but for Site Health it should
// always rely on the latest results.
wp_update_https_detection_errors();
$result = array(
'label' => __( 'Your website is using an active HTTPS connection' ),
'status' => 'good',
@ -1521,28 +1525,54 @@ class WP_Site_Health {
);
if ( ! wp_is_using_https() ) {
// If the website is not using HTTPS, provide more information about whether it is supported and how it can
// be enabled.
$result['status'] = 'critical';
$result['label'] = __( 'Your website does not use HTTPS' );
if ( wp_is_site_url_using_https() ) {
if ( is_ssl() ) {
$result['description'] = sprintf(
'<p>%s</p>',
sprintf(
/* translators: %s: URL to General Settings screen. */
__( 'You are accessing this website using HTTPS, but your <a href="%s">WordPress Address</a> is not set up to use HTTPS by default.' ),
esc_url( admin_url( 'options-general.php' ) )
/* translators: %s: URL to Settings > General > Site Address. */
__( 'You are accessing this website using HTTPS, but your <a href="%s">Site Address</a> is not set up to use HTTPS by default.' ),
esc_url( admin_url( 'options-general.php' ) . '#home' )
)
);
} else {
$result['description'] = sprintf(
'<p>%s</p>',
sprintf(
/* translators: %s: URL to General Settings screen. */
__( 'Your <a href="%s">WordPress Address</a> is not set up to use HTTPS.' ),
esc_url( admin_url( 'options-general.php' ) )
/* translators: %s: URL to Settings > General > Site Address. */
__( 'Your <a href="%s">Site Address</a> is not set up to use HTTPS.' ),
esc_url( admin_url( 'options-general.php' ) . '#home' )
)
);
}
} else {
if ( is_ssl() ) {
$result['description'] = sprintf(
'<p>%s</p>',
sprintf(
/* translators: 1: URL to Settings > General > WordPress Address, 2: URL to Settings > General > Site Address. */
__( 'You are accessing this website using HTTPS, but your <a href="%1$s">WordPress Address</a> and <a href="%2$s">Site Address</a> are not set up to use HTTPS by default.' ),
esc_url( admin_url( 'options-general.php' ) . '#siteurl' ),
esc_url( admin_url( 'options-general.php' ) . '#home' )
)
);
} else {
$result['description'] = sprintf(
'<p>%s</p>',
sprintf(
/* translators: 1: URL to Settings > General > WordPress Address, 2: URL to Settings > General > Site Address. */
__( 'Your <a href="%1$s">WordPress Address</a> and <a href="%2$s">Site Address</a> are not set up to use HTTPS.' ),
esc_url( admin_url( 'options-general.php' ) . '#siteurl' ),
esc_url( admin_url( 'options-general.php' ) . '#home' )
)
);
}
}
if ( wp_is_https_supported() ) {
$result['description'] .= sprintf(
@ -1561,6 +1591,36 @@ class WP_Site_Health {
__( 'Talk to your web host about supporting HTTPS for your website.' )
);
}
} elseif ( ! wp_is_https_supported() ) {
// If the website is using HTTPS, but HTTPS is actually not supported, inform the user about the potential
// problems.
$result['status'] = 'critical';
$result['label'] = __( 'There are problems with the HTTPS connection of your website' );
$https_detection_errors = get_option( 'https_detection_errors' );
if ( ! empty( $https_detection_errors['ssl_verification_failed'] ) ) {
$result['description'] = sprintf(
'<p>%s</p>',
sprintf(
/* translators: %s: URL to Settings > General > WordPress Address. */
__( 'Your <a href="%s">WordPress Address</a> is set up to use HTTPS, but the SSL certificate appears to be invalid.' ),
esc_url( admin_url( 'options-general.php' ) . '#siteurl' )
)
);
} else {
$result['description'] = sprintf(
'<p>%s</p>',
sprintf(
/* translators: %s: URL to Settings > General > WordPress Address. */
__( 'Your <a href="%s">WordPress Address</a> is set up to use HTTPS, but your website appears to be unavailable when using an HTTPS connection.' ),
esc_url( admin_url( 'options-general.php' ) . '#siteurl' )
)
);
}
$result['description'] .= sprintf(
'<p>%s</p>',
__( 'Talk to your web host about resolving this HTTPS issue for your website.' )
);
}
return $result;
@ -2200,10 +2260,6 @@ class WP_Site_Health {
'label' => __( 'MySQL utf8mb4 support' ),
'test' => 'utf8mb4_support',
),
'https_status' => array(
'label' => __( 'HTTPS status' ),
'test' => 'https_status',
),
'ssl_support' => array(
'label' => __( 'Secure communication' ),
'test' => 'ssl_support',
@ -2248,6 +2304,12 @@ class WP_Site_Health {
'has_rest' => true,
'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_loopback_requests' ),
),
'https_status' => array(
'label' => __( 'HTTPS status' ),
'test' => rest_url( 'wp-site-health/v1/tests/https-status' ),
'has_rest' => true,
'async_direct_test' => array( WP_Site_Health::get_instance(), 'get_test_https_status' ),
),
'authorization_header' => array(
'label' => __( 'Authorization header' ),
'test' => rest_url( 'wp-site-health/v1/tests/authorization-header' ),
@ -2614,7 +2676,7 @@ class WP_Site_Health {
// Don't run https test on development environments.
if ( $this->is_development_environment() ) {
unset( $tests['direct']['https_status'] );
unset( $tests['async']['https_status'] );
}
foreach ( $tests['direct'] as $test ) {

View File

@ -9,28 +9,53 @@
/**
* Checks whether the website is using HTTPS.
*
* This is based on whether the home and site URL are using HTTPS.
* This is based on whether both the home and site URL are using HTTPS.
*
* @since 5.7.0
* @see wp_is_home_url_using_https()
* @see wp_is_site_url_using_https()
*
* @return bool True if using HTTPS, false otherwise.
*/
function wp_is_using_https() {
if ( 'https' !== wp_parse_url( home_url(), PHP_URL_SCHEME ) ) {
if ( ! wp_is_home_url_using_https() ) {
return false;
}
return wp_is_site_url_using_https();
}
/**
* Checks whether the current site URL is using HTTPS.
*
* @since 5.7.0
* @see home_url()
*
* @return bool True if using HTTPS, false otherwise.
*/
function wp_is_home_url_using_https() {
return 'https' === wp_parse_url( home_url(), PHP_URL_SCHEME );
}
/**
* Checks whether the current site's URL where WordPress is stored is using HTTPS.
*
* This checks the URL where WordPress application files (e.g. wp-blog-header.php or the wp-admin/ folder) are
* accessible.
*
* @since 5.7.0
* @see site_url()
*
* @return bool True if using HTTPS, false otherwise.
*/
function wp_is_site_url_using_https() {
// Use direct option access for 'siteurl' and manually run the 'site_url'
// filter because site_url() will adjust the scheme based on what the
// filter because `site_url()` will adjust the scheme based on what the
// current request is using.
/** This filter is documented in wp-includes/link-template.php */
$site_url = apply_filters( 'site_url', get_option( 'siteurl' ), '', null, null );
if ( 'https' !== wp_parse_url( $site_url, PHP_URL_SCHEME ) ) {
return false;
}
return true;
return 'https' === wp_parse_url( $site_url, PHP_URL_SCHEME );
}
/**
@ -104,7 +129,7 @@ function wp_update_https_detection_errors() {
if ( ! is_wp_error( $response ) ) {
if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
$support_errors->add( 'bad_response_code', wp_remote_retrieve_response_message( $response ) );
} elseif ( false === wp_is_owned_html_output( wp_remote_retrieve_body( $response ) ) ) {
} elseif ( false === wp_is_local_html_output( wp_remote_retrieve_body( $response ) ) ) {
$support_errors->add( 'bad_response_source', __( 'It looks like the response did not come from this site.' ) );
}
}
@ -159,7 +184,7 @@ function wp_cron_conditionally_prevent_sslverify( $request ) {
* @param string $html Full HTML output string, e.g. from a HTTP response.
* @return bool|null True/false for whether HTML was generated by this site, null if unable to determine.
*/
function wp_is_owned_html_output( $html ) {
function wp_is_local_html_output( $html ) {
// 1. Check if HTML includes the site's Really Simple Discovery link.
if ( has_action( 'wp_head', 'rsd_link' ) ) {
$pattern = esc_url( site_url( 'xmlrpc.php?rsd', 'rpc' ) ); // See rsd_link().

View File

@ -85,6 +85,25 @@ class WP_REST_Site_Health_Controller extends WP_REST_Controller {
)
);
register_rest_route(
$this->namespace,
sprintf(
'/%s/%s',
$this->rest_base,
'https-status'
),
array(
array(
'methods' => 'GET',
'callback' => array( $this, 'test_https_status' ),
'permission_callback' => function () {
return $this->validate_request_permission( 'https_status' );
},
),
'schema' => array( $this, 'get_public_item_schema' ),
)
);
register_rest_route(
$this->namespace,
sprintf(
@ -199,6 +218,18 @@ class WP_REST_Site_Health_Controller extends WP_REST_Controller {
return $this->site_health->get_test_loopback_requests();
}
/**
* Checks that the site's frontend can be accessed over HTTPS.
*
* @since 5.7.0
*
* @return array
*/
public function test_https_status() {
$this->load_admin_textdomain();
return $this->site_health->get_test_https_status();
}
/**
* Checks that the authorization header is valid.
*

View File

@ -13,7 +13,7 @@
*
* @global string $wp_version
*/
$wp_version = '5.7-alpha-50071';
$wp_version = '5.7-alpha-50072';
/**
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.