We’ve long allowed users to access DocumentCloud’s tools over an encrypted HTTPS connection. Now, we’ve made it mandatory. Next time you log in to your DocumentCloud account, you will be redirected to the secure version of your workspace.

When you use an unencrypted HTTP connection to access a website, your request and the site’s response are all sent over the network in readable clear text, which is trivially easy to intercept and read. Without HTTPS, it is actually possible for someone hijack your connection to DocumentCloud, inserting or altering the content that you’re viewing. So we think HTTPS is worth using.

If you’re interested in the technical subtleties of implementing SSL, read on.

Our first step was to ensure that all of DocumentCloud works over HTTPS as well as HTTP, without generating mixed-mode warnings. We use domain-relative URLs as much as possible; when an absolute URL is needed, we have methods, in both Ruby and JavaScript, to generate the appropriate prefix. One nice trick is to take advantage of browser support for the protocol-relative URL, which can be used to request resources from an external domain while preserving the current protocol. We use …

//twitter.com/favorites/documentcloud.json

… on our homepage to grab the last few tweets we’ve liked, without having to worry about whether a viewer is using HTTP or HTTPS.

Ideally, we’d have “httponly” set to true, to prevent possible XSS stealing of cookie data, but unfortunately, we use a Flash-based document uploader that needs to be able to read the session cookie, and echo it back in order to authenticate the upload. For now, we’ll just have to remain vigilant against XSS attacks.

If you’re currently on Rails 2.3, I recommend upgrading to Rails 2.3.10 if you’re using HTTPS-only sessions. There’s a bug in previous versions that clobbers the session cookie if the visitor ever happens to load a non-HTTPS page on your site, while logged in. We want to be able to serve plain HTTP pages to folks without accounts, and HTTPS pages to logged-in contributors, so this is important for us.

Because the session cookie is now only being sent for HTTPS requests, your server now has no way of knowing if a visitor is logged in, when they visit an HTTP page. We get around this by adding a second, insecure cookie, which serves as a simple flag that the visitor has an active session:

cookies['dc_logged_in'] = {:value => 'true', :httponly => true}

When they log out, this cookie is cleared. With the “logged_in” cookie in hand, we can now redirect visitors with an active session to the HTTPS version of any page. If a friend shares a link to a document with you, and you have the “logged_in” cookie, you’ll be redirected to the secure version of the page where you’re allowed to annotate the document.

The last piece of the puzzle is the “before filter” that handles this redirect.

I hope that this rundown of the steps we’ve taken to enable HTTPS-by-default for DocumentCloud is helpful. If you find any holes in our approach, or see room for improvement — for example, a technique that avoids relying on Flash having access to the session cookie — comments are appreciated.