Using https with stunnel and ssl_wrapper

Whilst randomly wandering around GitHub a few weeks ago, I noticed ssl_wrapper, which I thought was interesting. Actually, I quite liked the idea of moving the https stuff into a seperate module. It means that any vulnerabilities found in the SSL/TLS stuff could be patched without having to do anything to the actual web server. I am also a fan of the philosophy of smaller pieces of code which can be well tested independently. I suppose this is just the Unix philosophy. But whatever you call it; I liked the idea.

So I had a bit of a play with ssl_wrapper, and even forked the repository to make the basic instructions a bit easier for me to follow, including the creation of a certificate for testing.

So I tried it out by running my own CPU Monitoring webserver over an https connection. However, in Chrome, I noticed that Google considers it to be using 'obsolete cryptography', like this:

I know that Chrome says this about a lot of existing sites, but I thought that it would be a good idea to try and make that message go away. But so far, I have not managed to do that with ssl_wrapper. In the meantime, I have logged an issue on GitHub.

UPDATE: this has now been fixed (but not by me, by the original authors). You can use ssl_wrapper and Chrome will say you're using 'modern cryptography'.

But since I was now interested in all this stuff, I decided to go and look and see if there are alternatives. Indeed there are, and a good one is stunnel. On my Ubuntu box installing it was a breeze, like this:

sudo apt-get install stunnel4

NOTE: I found that it is sometimes important to refer to stunnel4 with the '4' at the end, because your machine might already have an older version.

I was able to take the same certificate I was using with ssl_wrapper and set it up in stunnel. But straight away I found that Chrome was happier, and declared that I was using modern cryptography, like this.

Nice! Another advantage of stunnel is that there has been more recent activity on maintaining the code, which is somewhat comforting.

So, I am now setting up a seperate GitHub repository to help me to test stunnel on various Linux boxes (I have yet to try it on my Rasperry Pi, for example). It means I can be lazy and do this:

sudo apt-get install stunnel4
git clone https://github.com/davidsblog/stunnel4_config
cd stunnel4_config
sudo make

Which is a pretty painless way to test it out on different machines.

WCF HTTP Basic Authentication in Code

So I wanted to build a WCF service with a very simple authentication mechanism, and I thought that it would be good to start with my own implementation of http basic authentication - and then I could go from there, adding my own extras to the protocol if I wanted. But I thought that basic authentication over https would at least be a start.

And even though the username and password are sent in clear text, doing that over an https connection should be safe since it's encrypted before going over the wire.

Finally, I wanted to do the whole lot in code, so that I can deploy it to some hosted space without fiddling around in IIS. But also because I like code :-)

The good thing is that basic authentication is supported by most browsers, so I could expose the WCF service as web methods and test it very easily. I have assumed that since it works with all the major browsers I have implemented the protocol correctly.

The end result was a custom attribute which can be added to a WCF service and does all the work for you. The only other thing that needs to be done is modify the method which decides if a user is valid or not.

Here is the source code (click the image to download):

I'll post an example of how to use it (in Visual Studio 2012) in another blog.

Security for login cookies with ASP.Net MVC3

I was reading here about how it's a bad idea to log into your application using SSL (https) and then revert back to http for subsequent pages. If you do that then you'll send the authentication token over an unencrypted connection, which is a bad thing.

Whilst wondering if there was an easy way to solve that problem, I wrote some code to try and enforce a secure connection whenever the user was authenticated. So I wrote my own [RequireHttpsWhenAuthenticatedAttribute] which inherited from [RequireHttpsAttribute]. The idea was that you apply it to your whole site from your global.asax, and then https will *automatically* be turned on (and enforced) when users are logged in.

After posting that code, I got an e-mail from Andy Brown (thanks Andy) pointing out that if a logged in user switches to http by editing the address in their browser, the cookie will have already been posted back to the site by the time my new attribute is able to do anything. To be totally safe you'd have to assume that the cookie is already compromised at that point. I then realised that even if the site signs them out, the cookie could still be used by a hijacker until it times out.  For example, this article says “Even after the user has logged out of the application and the developer has called FormsAuthentication.SignOut, the authentication ticket remains valid until its time-to-live (TTL) expires, so it can be used by an attacker to impersonate another user.” 

So I went back to the drawing board to try and find an even better way.

In the end, the best option seems to be simply using this option when you set up forms authentication in your web.config:

requireSSL="true"

Rather than refer to your whole site, this attribute just applies to the authentication cookie, meaning the the browser should only send the cookie over https. Using that setting does the same job that my code was trying to do, only better. So I don't need any special code after all.