Quick HTTPS tests with Nginx

Why

In reading the article Dos and Don’ts of Client Authentication on the Web, I learnt two important things about cookies. And yes, the article dates from 2001, so you probably know all this, sorry I’m late.

The first one is that cookies for a given domain are sent along every HTTP requests. Ok, not a big deal but good to know.

The second one is that cookies not flaged as secure, even when only created or accessed throuth HTTPS requests, where sent along in plain text with all the HTTP requests (note the lack of “S” after HTTP).

The consequences of this are pretty scary: if you use a cookie as authenticator for your web app to grant your users some restricted access, and forget to flag it as secure, your users authenticators will leak on the internet as plain text everytime your users access a HTTP page of your site, such as your main public home page. So anyone eavesdropping can use these plain text authenticators to impersonate your users and gain restricted acess.

I wasn’t sure I had read correctly though, as it seemed quite a dangerous behavior. So I had to try it and see it for myself.

So I had to test quickly

I planned to setup a minimal http server, with two simple html pages, one served as plain HTTP (e.g. http://localhost/index.html ), and the other served through HTTPS (e.g. https://localhost/secure.html ).

Once I have this running, I’ll be able to make this simple tests:

If the cookie created for the HTTPS page is available in plain text in the HTTP Analyzer log for the HTTP page request, then this test will confirm what I read.

Setup a simple HTTPS server

My favorite tool to start a HTTP server on a local directory is a one liner:

$ python -m SimpleHTTPServer

Unfortunately, it doesn’t help with HTTPS, so I had to look for another simple solution.

Since I heard more and more about the Nginx HTTP server these years, I decided it was the occasion to try it.

Generating a self-signed SSL certificate

But first, to generate a self-signed SSL certifiate and key (later referred to as ssl.crt and ssl.key), I used openssl and this guide

Installing Nginx

Installing Nginx involve little more than downloading the source code, then the usual:

$ ./configure
$ make
$ sudo make install

Setup a small Web site and start the server

I created the default Nginx dirs to host conf, logs, and static files to serve:

$ mkdir conf logs html

Then I needed to write the two pages, html/index.html and html/secure.html with just the simplest header and body. Nothing special here.

Next step is to copy the default Nginx conf as a template to edit:

$ cp /usr/local/nginx/conf/nginx.conf.default conf/nginx.conf

Edit the conf slightly, pointing to /usr/local/nginx/conf/mime.types when necessary, to the ssl cert and key, and to my small html pages.

include       /usr/local/nginx/conf/mime.types;
...
listen 80;
location / {
  root   html;
  index  index.html;
}
...
listen 443;
ssl_certificate      ssl.crt;
ssl_certificate_key  ssl.key;
location / {
  root   html;
  index  secure.html;
}

Voilą, all I need is to start the Nginx server from here:

$ nginx -p .

When my test is over, I can stop the server with:

$ kill `cat logs/nginx.pid`

Lesson learned

  1. Designing a Web authentication protocol is hard, don’t do it yourself. But if you must, and you use a cookie to store an authenticator, make sure the cookie is flagged as “secure”.

  2. Nginx looks simple to learn, and easy to setup for a small test.

blog comments powered by Disqus