SSL and Cookies in WordPress 2.6

WordPress 2.6 includes better support for visiting the admin over SSL. Part of this support involves making sure authorization cookies are delivered only over SSL-encrypted HTTPS sessions.  To accommodate this while still allowing the option of visiting the admin over plain http, 2.6 moves from a single cookie setup to a three cookie setup.

In previous releases, WP set one cookie.  This cookie was delivered to all parts of your blog over both secure SSL connections and regular, unsecured connections.  It was delivered to the front page of the blog and to the admin pages.  Delivering a cookie to the front page allows WP to display inline editing and logout links for the currently logged in user.  To properly support SSL, WP needs to be able to restrict delivery of the auth cookie to only secure SSL sessions.  If WP stuck with a single cookie and delivered it only over secure sessions, that cookie would not be delivered to the front page since most people don’t visit the front page of their blogs over SSL.  Thus, WP would be unable to display info related to the current user on the front page.

To remedy this, WordPress 2.6 sets separate “logged in” and “auth” cookies.  The logged in cookie is delivered for all pages of your blog over both SSL and non-SSL sessions.  The logged in cookie cannot be used to access the admin.  It merely indicates that a particular user is currently logged in. The logged in cookie cannot be used to make changes to the blog.

The auth cookie, on the other hand, is delivered only for the admin area and can be used to make changes to the blog.  If you login via https, your auth cookie will be delivered only for SSL sessions.  If you login over https and later visit your admin via regular http, you will have to log in again to get a non-SSL auth cookie. By default, you have the option of visiting your admin either via http or https.  If you want to force all admin sessions to be over https, add the following to your wp-config.php:

define(‘FORCE_SSL_ADMIN’, true);

This will prevent non-SSL logins to your blog. This means you will never have an auth cookie delivered in the clear.  If you want to force logins to be over SSL to prevent usernames and passwords from being sent in the clear while letting your users have the choice of using http or https when visiting the admin, add this to your wp-config.php:

define(‘FORCE_SSL_LOGIN’, true);

This does not force all cookies to be delivered over SSL.  The user has a choice between the greater security of an https session and the greater speed of an http session.  If you want to remove this choice and force secure https sessions, FORCE_SSL_ADMIN is for you.

With these new cookies comes new secret keys for signing them.  Recall that WordPress 2.5 introduced SECRET_KEY as a means of adding a little extra security to cookie signing.  If you intend to use the SSL support in 2.6, you will probably want to define the secret key for the secure cookie.  If you don’t intend to use SSL, you can stick with your existing SECRET_KEY.  Here’s an example of what the new secret key definitions look like:

define(‘AUTH_KEY’, ‘put your unique phrase here’);
define(‘SECURE_AUTH_KEY’, ‘put your unique phrase here’);
define(‘LOGGED_IN_KEY’, ‘put your unique phrase here’);

You should change those sample phrases to unique, preferably random phrases.  Each key should have a different phrase.  Visit http://api.wordpress.org/secret-key/1.1/ to get a set of random keys that you can cut-and-paste into your wp-config.php.  Once again, if you don’t intend to use SSL, you can stick with the SECRET_KEY you already have.

This should be mostly transparent to plugins and themes. I say mostly because there are some themes that send POST and AJAX requests to files within the themes directory.  The auth cookies are delivered only to the wp-admin and wp-content/plugins directories, so files directly loaded from wp-content/themes will not see the cookies.  Themes should send their POST and AJAX requests to the admin-post.php or admin-ajax.php files.  I’ve added a short article to the codex on how themes and plugins should handle their POST and AJAX requests.

Plugins might also create links that are not properly prefixed with ‘https’.  Any content loaded into a secure page must come via an https link to avoid warnings from the browser about the content being only partially encrypted.  WordPress 2.6 introduces five new functions that take care of using the proper protocol when loading CSS, JS, and other files into an SSL-encrypted admin page.  They are site_url(), admin_url(), includes_ur(), plugins_url(), and content_url().  Each accepts an optional path relative to the site, admin, include, plugins, and content urls, respectively.  For example, to link to wp-content/plugins/foo/foo.php use plugins_url(‘foo/foo.php’).  Plugins that load CSS and JS via relative links do not need to use these functions.  Relative links will automatically use the proper protocol.

If your host supports SSL, WordPress 2.6 enables you to make use of that support in a secure manner.  Enjoy, and help us make SSL support better by reporting any bugs you find.

64 thoughts on “SSL and Cookies in WordPress 2.6

  1. Ryan,

    On the topic of SSL and cookies… Is there a way to define the https URL as a constant in wp-config?

    For example https://mybloghere.com/wp-admin/ works, but for a second blog running on the same host as a virtual, I’d like to use https://secondblog.com:444/ (not 443) for administration.

    This way I can bind the second SSL instance to 444 and have two separate SSL certs, root directories, etc.

    Sorry for posting here versus the forum 🙂

    Jan Dembowski

  2. Pingback: Wordpress 2.6
  3. SSL admin sounds great, although I need it to support a different prefix for SSL URLs than for non-SSL, so I will have to stick with Admin-SSL (once it works with 2.6 again) until 2.7 or whenever built-in SSL support gets a bit more flexible.

    Can you guys put SSL into the docs? The release announcement links to wikipedia for a definition of SSL, and this blog posting is the only documentation I’ve seen, but I got here through Google — no pointers in the announcement or WP Docs.

  4. Hi Ryan,

    I had to change the single quotation marks to straight marks (not cute or curly or whatever people call them) from the formatted ones in your post above. Then it worked.

    define(‘FORCE_SSL_LOGIN’, true);
    define(‘FORCE_SSL_ADMIN’, true);

    I have them both forced.

    Thanks for providing the information.

    Tom Usher

  5. I was upgrading to 2.6 and activating some plugins after the upgrade was done, then this message appeared:

    Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 223115 bytes) in /home/ysamphyc/public_html/wp-admin/includes/plugin.php on line 4

    And I cannot log in the admin panel now. 🙁 Please help!

  6. Hi,

    I’m trying to use SSL-encrypted admin sessions.

    Thus, I added those two mentioned define(…) lines to my wp-config.php, but when trying to open https://www.myfoosite.bar/wp-admin Firefox3 tells me in an error message that the site was sending it into an indefinite redirect loop.
    (Without the two lines I can access the page through SSL correctly, but then all links/image-srcs are still http://)

    What’s wrong here? Or aren’t those two lines not enough to enable SSL admin sessions? Do I need an extra plugin with WP 2.6 just laying out the foundation for its use?

    Thanks!
    Tobias

  7. I can’t find a comprehensive list of all defines that can be made in the wp-config.php file, nor instructions on how to move wp-config.php and wp-content to new locations.

  8. Hi Ryan

    The SSL features look promising – only there are various problems, for example plugins (like WP Stats) that require non-HTTPS script files/stylesheets, and so you get a ‘partially encrypted page’.

    Also, my plugin, Admin SSL (which was originally based on your first SSL plugin, Secure Admin), allows you to use Shared SSL as well as Private SSL – WordPress 2.6 will only work with Private SSL. It also allows individual pages to be secured, and actually works when you only want wp-login.php to be secured (I just can’t get that to work on my own blog!).

    Perhaps some of these features could be included in WP 2.7? I’d be happy to liaise with you to share my hard-fought experience of wrestling with Shared SSL, and the various different features.

    Cheers

    bcg

Leave a Reply to Jan EricCancel reply