format internet:

…please wait (42% completed)…

Archive for March, 2011

How we improved FACTURAgem security, or how to set HTTPS for your rails application

Posted by javier ramirez on March 31, 2011

As you probably know, one of the products in my company is FACTURAgem, a web application for making simple invoices targetted to those users who are currently invoicing using word, excel or a notepad and a ballpoint.

Since your invoices are something you don’t want to share with the rest of the word, all the pages protected by login were securily encrypted and served via https since the first day, and the session cookie was automatically expired when the browser is closed, so the system was pretty safe.

Still, there was a very small chance of someone hijacking your session, if you were using FACTURAgem and you happened to be sharing a public network with a hacker nearby who was interested in accessing your FACTURAgem account. Due to the profile of both our users and our application this scenario was not likely to happen, and we never had any security breach since we launched the product.

However, with the proliferation of public networks and the quick adoption of smartphones, ipads, netbooks and a myriad of always-connected portable devices, we wanted to add an extra layer of security for our users, so now they can safely use FACTURAgem at any place without any worries.

Since yesterday, all the pages in FACTURAgem, both private and public, are securily served via https. Even if you forget to include the “s” when accesing the apllication, our servers will redirect appropriately to the safest version.

For the technically savvy, I will explain the highlights of the process:

note: FACTURAgem is running on an Apache/Passenger/Rails stack. If you are using a different setup, details might be differ, but the spirit is the same.

We had to cover different fronts of the https problem:

Configuring a certificate and SSL virtual host for Apache.

This was already done in our case since the beginning of the project. There’s a lot of information out there about how to do this.

Telling Apache to redirect all the traffic to https

We had to instruct our non-ssl virtual host to redirect all the traffic to the SSL one, so if you type http://www.facturagem.com/help you should be redirected to https://www.facturagem.com/help instead.

This is easily done with:

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

Unfortunately, in our case, we had an extra constraint. There are a couple of subdirectories we don’t want to put under SSL, because they are served by an external service that cannot run under https. For those pages, we will not store any session information, so they will not be a security problem. All we had to do is telling Apache not to redirect if the url is in one of those directories

RewriteEngine on
RewriteCond %{HTTPS} off
RewriteCond %{REQUEST_URI} !.(fictional_directory_name|another_fictional_directory_name).*
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

By doing this, if you try to visit http://www.facturagem.com/fictional_directory_name/whatever you will not be redirected to https.

Making sure we marked the cookie as secure, so we are 100% sure it will never be passed to non-encrypted pages

By setting a cookie as “secure” your browser is smart enough to send the cookie back only when asking for a SSL resource. That way, even if you are browsing unsafe pages from the same domain, the cookie will not be transmitted, so your session is not subject to attacks.

If you are setting your cookies “manually”, secure is one of the attributes you can set. But if you are using session cookies in Rails, it’s as easy as setting an extra parameter when configuring your session cookie.

ActionController::Base.session = {
:key => '_your_application_secure_session_id',
:secret => '11111222312321321321321313213213213213213213213237761223213213213213131231231321321312',
:secure => Facturagem.config.secure_cookie
}

Some things to consider here. If you are changing a live application, as it was our case, it’s a good idea to change the name of the cookie. That way, you are sure everybody is going to be using the secure version. Otherwise, users with a valid cookie would still use the non-secure version in some browsers. By changing the name, you are sure everyone is setting a new cookie and everyone is secure using your site. The collateral effect is you will be signing out all of the users browsing your site, so take it into account.

Also, note how we are using a config variable to set a secure cookie (or not). This way, our developers can work without locally enabling SSL.

Removing any references to http external resources, so we avoid the “mixed content” message in some browsers

By this point everything should be working fine, but if you are using any resources directly by absolute URL (as is the case of external js or, in many ocassions, images referenced from your stylesheets), then you will be having the “mixed content” message and your users will feel something is not right.

Your first impulse can be changing all the “http://” ocurrences in your files for “https://”. That would fix the problem on production, but should any developer work without SSL, she would experience the mixed content alerts.

There is a not-so-known-but-perfectly-fine solution for this. You can use relative network-path references , also known as protocol relative urls. To make a long story short, if you write ‘//www.google.com/jsapi’ it will use http or https depending on which protocol you are using on the current page. That way, you can forget about which schema you are on. There’s a caveat with explorer downloading twice the javascript files (at least until IE8 there was), and if you want more info Paul Irish has it ready for you.

That was it! by following those steps we were able to make our site more secure and it took just some hours to set up. Now you can use FACTURAgem when you need to, without worrying who your neighbours are.

If you are out of Spain, pay attention to @facturagem, because we are going to be launching an international version pretty soon.

Advertisements

Posted in aspgems, development, javier ramirez, madrid, ruby on rails | 2 Comments »