Latest Updates: Our Blog

HTTPS by Default

Posted
Feb 4th, 2011

Tags
Workspace

Author
Jeremy Ashkenas

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.

Note: EFF’s Chris Palmer has written a great guide to deploying https correctly, which might be a good starting point if this is already over your head.

Nginx handles the SSL itself, in a straightforward fashion, as long as you’ve compiled it with the SSL module turned on.

The next step was to move our cookie-based sessions over to HTTPS-only cookies, which can be configured in Rails fairly easily:

ActionController::Base.session = {
  :key          => 'document_cloud_session',
  :secret       => '[secret string]',
  :expire_after => 1.month,
  :httponly     => false,
  :secure       => true
}

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.

def prefer_secure
  if !request.ssl? && cookies['dc_logged_in'] == 'true'
    redirect_to :protocol => 'https://'
  end
end

before_filter :prefer_secure, :only => [:index, :show]

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.

2 Responses to 'HTTPS by Default'

Subscribe to comments with RSS

  1. avoiding flash for file uploads:

    * https://code.google.com/p/noswfupload/
    * https://code.google.com/p/jquery-html5-upload/

    (from about 10 minutes of digging on the ‘net)

    Daniel Kahn Gillmor

    5 Feb 11 at 1:45 pm

  2. You still let your login form outside https, wich means that you’re not addressing the main reason that https is being more and more used: you’re not protecting your users data.

    http://www.sslshopper.com/article-how-to-make-a-secure-login-form-with-ssl.html

    Read this and change your site, if you’re really want to be more secure.

    Diego Plentz

    9 Feb 11 at 10:09 pm

Leave a Reply