fromAugust 2012
Article:

Drupal and Secure Single Sign-on

It’s Time to Get Your Cookies in Order
0

It's Time to Get Your Cookies in Order

If you want to have a native, single sign-on solution that is deeply integrated into Drupal, there is really just one option: Bakery. If you aren't aware of the Bakery module, it is what creates single sign-on between sites like drupal.org and groups.drupal.org, as well as most of the DrupalCon sites.

If you're wondering why the module is called Bakery it's because it deals with the cookies, of course. A read through the module's code will introduce you to such cookies as the OATMEAL cookie, the CHOCOLATECHIP cookie, and a variety of others. I won't get into what they all do, but suffice to say that it's an amusing read.

Bakery is ideal for Drupal sites because it is capable not only of providing SSO, but also of syncing Drupal profile fields and user avatars — and handling some de-duping of accounts — on top of providing account proliferation across multiple sites.

What this means in practice is that you have a Bakery master site and Bakery slave sites. All logins and registrations actually go through the master. If a user visits slave site A and registers, upon form submission said user is actually redirected to the master site where a cookie is read containing all of the user's info; the account is created, an SSO cookie is dropped, and the user is redirected back to the site they signed up at. There the SSO cookie is read, a local account is created, and the user is logged in.

By and large this works very well, but there's a threat lurking inside of it: cookie security. Because users now have a cookie (the cookie name is CHOCOLATECHIP) on their system that essentially grants access to all your sites, someone sniffing that cookie can gain access to all your sites.

This isn't anything new. By default, most LAMP stacks drop cookies in what is known as mixed mode. A mixed mode cookie will be passed by the browser to the site whether the protocol is HTTP or HTTPS. This problem is present in single site solutions as well, but it is exacerbated in setups where you have SSO because it could expose your entire infrastructure — as opposed to just one site.

Imagine this scenario. You have installed securepages, or you use a custom module to ensure that all logged in users are redirected to HTTPS. However the SESS (session) cookie is dropped in mixed mode. While users browse your site (or administer it), they continually send that cookie over HTTPS. However, if a user closes their browser and then revisits your site by simply typing www.yoursite.com in their browser, that cookie is now sent over HTTP and its contents are visible to anyone sniffing along the way. Heaven forbid they do this in a coffee shop or on another public network. Access to your site has just been broadcast over whatever LAN they are on.

To solve this, one simply needs to set the php.ini variable session.cookie_secure to TRUE — either in the php.ini or with an ini_set() call. What that means is that any cookies dropped over HTTPS will only be subsequently sent over HTTPS.

We're all set, right? Problem solved? Not quite. A new problem has cropped up. A user visits your site, logs in and has authenticated access over HTTPS. Then they get an email that links to http://yoursite.com/read-this (or a tweet, or they close their browser and type a URL by hand); when they click it they aren't logged in! Why not? Because the SESS cookie that Drupal dropped to log them in is not available over HTTP.

This will confuse the heck out of your users and cause you no end of pain. Enter the Auth SSL Redirect module. This is a module created to perform a singular task. When a user logs in or registers, another cookie is dropped: AUTH_SSL. This cookie is always dropped in mixed mode. A user visiting your site over HTTP then sends this cookie to the site. A hook_init() in the module looks for this cookie and, if it is found, it redirects the browser to the same URL via HTTPS. If the user has the SESS cookie (or in Bakery's case the CHOCOLATECHIP SSO cookie), the user is authenticated and logged in.

A working scenario with Bakery in the mix performs like this: A user registers on slave site A, they are redirected to the master (where the account is created), the user is logged in, and the SSO cookie is dropped. Because of the session.cookie_secure setting these cookies will only be passed over HTTPS. Following that the Auth SSL Redirect module drops the AUTH_SSL cookie in mixed mode.

The user then manually types the URL to slave site B without specifying HTTPS. Because Auth SSL Redirect is in play the site detects that they should be redirected to HTTPS. The browser is redirected and the CHOCOLATECHIP cookie is sent. The website makes a request to the Bakery master server, validates the cookie, pulls the user's information over to that site, and then drops its local SESS cookie.

Voila! The user has been redirected to HTTPS, their account moved to slave site B, and been logged in, all automatically. The setup is secure and the sites behave to the user as though they are a singular entity that knows and authenticates them properly.

While Bakery works across Drupal 6 and 7 (a Drupal 5 version is also available, though not supported) it does not transfer roles in any scenario and does not transfer profile fields to/from Drupal 7 sites. If you are interested in a way to tackle this problem, it can be solved via the Services module. It adds the ability to synchronize user's profile fields and roles on slave sites. Check out the Enterprise Drupal Application Scaling article in this issue for more information regarding using the Services module to sync data.