Improved HTTPS detection and migration in WordPress 5.7

WordPress 5.7 will feature a number of enhancements which simplify the migrationMigration Moving the code, database and media files for a website site from one server to another. Most typically done when changing hosting companies. of a site from HTTPHTTP HTTP is an acronym for Hyper Text Transfer Protocol. HTTP is the underlying protocol used by the World Wide Web and this protocol defines how messages are formatted and transmitted, and what actions Web servers and browsers should take in response to various commands. to HTTPSHTTPS HTTPS is an acronym for Hyper Text Transfer Protocol Secure. HTTPS is the secure version of HTTP, the protocol over which data is sent between your browser and the website that you are connected to. The 'S' at the end of HTTPS stands for 'Secure'. It means all communications between your browser and the website are encrypted. This is especially helpful for protecting sensitive data like banking information.. As the foundation for providing the user with more accurate recommendations, WordPress will be able to detect whether the current environment already supports HTTPS. If this is the case, it provides a call-to-action button in the HTTPS status section in Site Health, which switches the site from HTTP to HTTPS with a single click.

Overall guidance in the Site Health section has been improved, now allowing hosting providers to supply a custom URLURL A specific web address of a website or web page on the Internet, such as a website’s URL www.wordpress.org with instructions or for a one-click update.

Walkthrough of the new feature with a quick demo, including highlighting of the problems this addresses

Detecting state of HTTPS and environment support

WordPress 5.7 introduces a new function wp_is_using_https(), which returns true if both the “Site Address” (home_url()) and “WordPress Address” (site_url()) are using HTTPS as their scheme. Essentially, changing both of these URLs to HTTPS formally indicates that the site is using HTTPS. While there are other ways to enable HTTPS partially in WordPress (e.g. with the FORCE_SSL_ADMIN constant), the new detection mechanism focuses on using HTTPS throughout the entire site, i.e. its frontend and backend.

In addition to providing a single function for checking whether HTTPS is being used, a new detection function wp_is_https_supported() can be called to check whether the environment supports HTTPS correctly. This is now used in Site Health to provide more accurate feedback: If the environment already supports HTTPS, the user can make the switch instantly, without involving their hosting company. Under the hood, the detection function is based on a new internal option https_detection_errors, which is controlled by a twice-daily Cron hook that works as follows:

  • It issues a request to the HTTPS version of the site with the sslverify argument enabled.
    • If the request succeeds, there is already a working SSLSSL Secure Sockets Layer. Provides a secure means of sending data over the internet. Used for authenticated and private actions. certificate in place.
      • In this case, the function also checks whether the HTMLHTML HyperText Markup Language. The semantic scripting language primarily used for outputting content in web browsers. body from the response actually belongs to the same WordPress site; this is typically the case, but the extra check is needed to cater for sites and environments that e.g. place custom HTML content under the URL. If the HTML body belongs to the same WordPress site, the environment is ready to be switched to HTTPS. Otherwise, switching to HTTPS then cannot reliably be accomplished by WordPress itself because the content is not entirely controlled by it.
    • If the request fails, it attempts the same request again, except that the sslverify argument is now disabled.
      • If that request succeeds, it means there is an SSL certificate, but it cannot be verified, which for example applies to self-signed certificates.
      • If that request fails as well, it means the site is entirely inaccessible over HTTPS.

The wp_is_https_supported() function simply looks at the https_detection_errors option controlled by the Cron hook, and it returns true if there are no errors stored.

One-click migration to HTTPS

A major pain point in migrating a WordPress site from HTTP to HTTPS has been the need to fix all the hard-coded URLs in existing database content which were still using the HTTP version, to avoid mixed content warnings. These URLs are usually migrated with a database replacement pluginPlugin A plugin is a piece of software containing a group of functions that can be added to a WordPress website. They can extend functionality or add new features to your WordPress websites. WordPress plugins are written in the PHP programming language and integrate seamlessly with WordPress. These can be free in the WordPress.org Plugin Directory https://wordpress.org/plugins/ or can be cost-based plugin from a third-party or WP-CLIWP-CLI WP-CLI is the Command Line Interface for WordPress, used to do administrative and development tasks in a programmatic way. The project page is http://wp-cli.org/ https://make.wordpress.org/cli/, but that process is tedious and not intuitive to many WordPress administrators.

WordPress 5.7 introduces a new wp_replace_insecure_home_url() function which is hooked into various pieces of content to replace these insecure URLs on the fly. It relies on another new function wp_should_replace_insecure_home_url() which determines whether the URL replacement logic needs to run or not. All of the following conditions have to be fulfilled for the automatic content rewrites:

  • The site has to be using HTTPS, via wp_is_using_https().
  • A new internal flag option called https_migration_required has to be enabled. The option is automatically enabled when the “Site Address” and “WordPress Address” are switched to their HTTPS counterpart on a site with existing content. (In other words, a fresh_site that is immediately switched to HTTPS does not trigger the content rewrites logic.)
  • The “Site Address” and “WordPress Address” have to be using the same domain.

With the content rewriting of insecure URLs in place, the only change required to switch the site from HTTP to HTTPS is updating the “Site Address” and “WordPress Address” to their HTTPS counterparts. While this only entails updating two text input fields, it can still be simplified; this is why WordPress 5.7 includes another new function wp_update_urls_to_https() which updates both URLs accordingly. It also includes an extra check to verify that this resulted in WordPress correctly recognizing the site as using HTTPS; if not, the change automatically gets reverted to prevent any unexpected issues.

While the one-click migration introduced by WordPress 5.7 does not support advanced site configurations where e.g. “Site Address” and “WordPress Address” differ, it drastically simplifies migration in the common scenario; furthermore, the advanced configurations are often used by more technically savvy users that already know how to migrate to HTTPS anyway.

Administrators that would like to actually replace the URLs in the database can still do so. In that scenario, it is recommended to delete the https_migration_required option, to avoid the URL rewriting logic from running unnecessarily. Alternatively, the URL rewriting function can be unhooked entirely as follows:

remove_filter( 'the_content', 'wp_replace_insecure_home_url' );
remove_filter( 'the_excerpt', 'wp_replace_insecure_home_url' );
remove_filter( 'widget_text_content', 'wp_replace_insecure_home_url' );
remove_filter( 'wp_get_custom_css', 'wp_replace_insecure_home_url' );

Improved Site Health guidance

The HTTPS Status section in Site Health has been improved to guide the user more towards using HTTPS. If the environment already supports HTTPS (via wp_is_https_supported()), the UIUI User interface will now include a button to switch both site URLs with a single click (using wp_update_urls_to_https()). Users will need to have a new update_https metaMeta Meta is a term that refers to the inside workings of a group. For us, this is the team that works on internal WordPress sites like WordCamp Central and Make WordPress. capability in order to perform the switch; by default this capability is granted to every user that can both manage_options and update_core.

HTTPS Status section when HTTPS is not yet supported by the environment
HTTPS Status section when HTTPS is already supported by the environment

Various minor improvements have been made to more accurately describe the site’s configuration. For example, sites that rely on the WP_HOME or WP_SITEURL constant will see this reflected now, since that means WordPress cannot automatically update these URLs.

The severityseverity The seriousness of the ticket in the eyes of the reporter. Generally, severity is a judgment of how bad a bug is, while priority is its relationship to other bugs. of not using HTTPS in the overall HTTPS Status Site Health test is now set to “critical”, whereas before it was “recommended”. This means that sites which do not use HTTPS will now see the “Should be improved” state in the Site Health dashboard widgetWidget A WordPress Widget is a small block that performs a specific function. You can add these widgets in sidebars also known as widget-ready areas on your web page. WordPress widgets were originally created to provide a simple and easy-to-use way of giving design and structure control of the WordPress theme to the user., highlighting this further.

Providing custom support URLs for switching to HTTPS

In order to further help to guide WordPress administrators towards the switch to HTTPS, hosting providers that have their own support content for how to switch to HTTPS can now provide these URLs to WordPress so that users can get to that guidance directly from their administration panel.

  • Hosts which offer their own dedicated HTTPS support content can provide the URL that by setting a WP_UPDATE_HTTPS_URL environment variable or by hooking into a new wp_update_https_url filterFilter Filters are one of the two types of Hooks https://codex.wordpress.org/Plugin_API/Hooks. They provide a way for functions to modify data of other functions. They are the counterpart to Actions. Unlike Actions, filters are meant to work in an isolated manner, and should never have side effects such as affecting global variables and output.. If no such URL is provided, the default URL links to this HTTPS support article.
  • Hosts which offer a utility to automatically switch the site to HTTPS can provide the URL to do so by setting a WP_DIRECT_UPDATE_HTTPS_URL environment variable or by hooking into a new wp_direct_update_https_url filter. If no such URL is provided, the default URL triggers the aforementioned WordPress one-click mechanism.

For reference, see TracTrac An open source project by Edgewall Software that serves as a bug tracker and project management tool for WordPress. tickets #47577 about HTTPS detection and #51437 about HTTPS migration.

Props to @timothyblynjacobs for proofreading

#5-7, #dev-notes, #https, #site-health