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 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.

[ via Ryan Boren ]

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.