How to Properly Provide Mixed HTTP and HTTPS Support

I've noticed that many sites seem to want to only support SSL partially, so that they don't have to invest in expensive SSL accelerators. While I can't necessarily say this fits in with my grand design to move the entire web over to SSL for good, if it has to be done, it might as well be done securely. This post attempts to describe the general pattern for how to do it.

The general idea is that you want to provide SSL for users to use only sometimes: for example when they are in a sketchy coffee shop, at the airport, or at the mercy of over 8000 hackers because they happened to be Vegas the first week of August.

The usage pattern you want is for users to normally use http, but if they hit your site via https, this means they want security, and their cookies should not then be vulnerable to theft.

The way to do this is via two sets of cookies: the actual authentication cookies, and an optional non-secure SSL marker cookie (which we'll call "WantsSSL"). When the user first logs into the site via http, they only get their authentication cookies set, and set as non-secure, to be transmitted over any type of connection. Then, if the user hits the site via https, they get the WantsSSL cookie set to be transmitted over any type of connection, and get all their authentication cookies upgraded to be SSL-only. The key is that since this cookie is not set as secure, it will be transmitted when the user happens to access the site via http (after once trying to use https). This will indicate the user is actually authenticated, but needs to be redirected back to https to actually use the site with their authentication cookies. If the WantsSSL cookie is not present and the user still has no authentication cookies, they need to be logged in as usual.

This way, as soon as the user starts using https, they are locked into it until they log out, and yet they also won't be logged out mysteriously if they accidentally hit the http url. Allowing the user to automatically downgrade to http is of course not secure, because the attacker on the local network can force them to visit the http url via a simple redirect.

This will enable people to normally use http for most of the time, but when they go to that sketchy coffee shop where disreputable characters tend to gather and glance at each other shiftily while conversing only via their laptops for some reason, they can use https and actually be secure until they log out again.

The one downside is that it is still possible for an attacker to clear the marker cookie, and make the user think they are logged out if they do accidentally visit the http version of the site, at which point they may log in again insecurely. So it isn't completely perfect if the user is sloppy about their URL prefix, but will at least provide security for people who know they want it. A small stopgap on the way to a completely SSLed web.

Update: 8/25/2008 9:00pm Pacific

There are is an additional subtlety to this approach that needs mentioning. If the user DOES NOT visit your site during their usage of an insecure network and they never end up promoting their cookies to SSL-only, they can still be stolen by injecting content elements for your site's domain into arbitrary pages, even though they do not visit your site at any point during their usage. The really unfortunate case is where users may think "Well, I will *never* use my account from open wifi, so I can stay in http". Unfortunately, these users will be more vulnerable than those who simply type https to be upgraded.

Obviously the more popular your site is, the more likely this injection is to happen. So at the end of the day for very popular sites with information that people will try to download, crawl or vandalize the best option to solve this is full SSL. However, in the meantime, for users who do tend to move about a lot on insecure networks, it is likely that most of the time, their cookies will already have been upgraded to SSL, and the above method will provide them with the security they need automatically (assuming they at least know that your site provides SSL, that is).

Is there an easy fix for drupal sites?

I'm using the SSL module for drupal and i'm wondering if i'm exposed to this exploit? If i am, is there a beginner way (e.g. a module to be installed) that will make the site more secure?

Re: Is there an easy fix for drupal sites?

Drupal has issues with cookie demotion currently. A patch was recently checked in to CVS, but is not out in the releases yet.

When I get a chance, I will document what needs to be done if they don't end up making it easy out of the box, as I use SSL on some of my drupal sites. It basically involves instructing php to use session.cookie_secure and then applying their patch.

Drupal will not support

Drupal will not support secure cookies out of the box, as there seem to be strong forces desperate to have mixed HTTP/HTTPS sessions for the same user _simultaneously_.

Perhaps a lot of external pressure may change this stance.

help to apply the patch

hello, i visited...

so having different cookies for http and https is still not easy, and many aspects don't work

if we manage to have the complete solution (always login data through ssl, user and admin pages alway encrypted, authenticated sessions always encrypted, session-cookies always encrypted, different cookies for http and https sessions) could we think to have a reasonable security under the point of view of the article on this page?

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

More information about formatting options

This question is for testing whether you are a human visitor and to prevent automated spam submissions.
  ___  __   __     _      ____    _  __
|_ _| \ \ / / / \ | _ \ | |/ /
| | \ V / / _ \ | |_) | | ' /
| | | | / ___ \ | _ < | . \
|___| |_| /_/ \_\ |_| \_\ |_|\_\
Enter the code depicted in ASCII art style.