Random Thoughts on Improving Internet Security

Disclaimer

IANACSE (I am not a computer security expert.) But…

When I was in my final year of high school, I had the opportunity to study with the Australian Mathematics Olympiad Squad. I didn’t make it into the team, but a friend of mine and I got close enough to be invited to the training, and be lectured to by Paul Erdos for a week. I’d love to say that this was an inspiring experience, but unfortunately the impenetrability of his accent was exceeded only by the material he was covering. It didn’t help that, alone among the participants, my friend and I hadn’t spent years in gifted programs and/or at universities getting exposed to graduate-level math.

For me, the highlight was a field trip to a presentation at a math conference about cryptography. I only understood the outlines of what the speaker was talking about at the time, but the subject matter was the theory underlying what is now known as public key cryptography. So, attending and not understanding that presentation, and a hazily recalled education in Pure Math, are my only special claims to domain knowledge.

The Problem(s)

The most commonly used internet protocols — http, ftp, and POP/IMAP/sendmail — are hopelessly insecure.

The standard solution for http is to switch to https.

With ftp at least there’s sftp. If your ISP doesn’t support sftp, use another ISP.

Email is pretty much a lost cause because even if your connection to your email provider is secure, the email transmission is not going to be, so anyone who cares about email is encrypting their email content using PGP or something similar.

I haven’t had an email exchange with anyone, ever, that required me to use PGP, so it’s obviously not very popular. By now, PGP should be built into every mail client and operate transparently (it would make spam harder and more expensive to send, too), instead our best option is usually webmail via https, or a proprietary solution like Microsoft Exchange or Lotus Notes (which has, laudably, been secure from the beginning — it’s a shame it sucks dead dog’s balls in pretty much every other respect).

OK, let’s ignore everything except http

I’ve recently been looking at implementing some kind of security for logging in to websites over http. The usual, simple solution for this is to switch over to https, but the vast majority of the world’s web servers are serving http, and this includes all kinds of services with logins and passwords that people don’t really think too carefully about. How likely is it that some username/password combination a given person uses for an insecure website (e.g. a blog, forum, or whatever) is also used for a secure website somewhere else? Even if https is secure (which is open to doubt), it’s undermined by the insecurity of http.

Here’s the actual form code for Digg.com‘s login form (modulo whitespace):

<form method="post" action="/login/prepare/digg">
<div class="form-row">
<label class="dialog-label" for="login-username">Digg Username</label>
<input class="login-digg-username text" name="username" value="" type="text">
</div>
<div class="form-row">
<label class="dialog-label" for="login-password">Digg Password</label>
<input name="password" class="login-digg-password text" type="password"> <a class="dialog-link forgot-link" href="/login">Lost username or password?</a>
</div>
<div>
<input name="persistent" checked="checked" type="checkbox"> <label class="inline"><strong>Keep me logged in on this computer</strong></label><br>
<input value="Login" type="submit">
</div>
</form>

I’m not trying to single out Digg — it’s just an example of a large scale, popular site that requires user logins and offers zero security. Facebook — a very high profile, popular site — is just as stupidly insecure (the relevant code is a bit harder to read). Why isn’t this a scandal?

It seems to me that it’s criminally negligent of the folks running these sites, and the people developing the most popular open source website software — phpbb, wordpress, drupal, etc. — not to have addressed this, when the solutions are so very straightforward and have been publicly and freely available for so long. Apple got into quite a bit of hot water — and rightly so — for (allegedly) not sufficiently securing MobileMe chatter between web apps and servers, but many of us spend a lot of time on all kinds of websites requiring passwords that make no real attempt at keeping our information safe.

  1. By default, during the setup of any of these programs, the admin should be forced to provide an encryption key, or — better — set parameters for automatically generating such a key for the website. Ideally the key would be refreshed periodically (or even created on-the-fly if the horsepower is available). Some security is better than no security at all, so even if the default key is “only” 64-bit this would be very helpful.
  2. The login page (and any other page where the user enters sensitive information) should simply incorporate JavaScript that takes the public key supplied by the server and encrypts it before posting it back to the website. Encryption in JavaScript, even on fairly slow machines and browsers, is close to instantaneous, and could be done in the background. If JavaScript is disabled, the code can warn the user and fall back to the usual (insecure) method.
  3. The web server then decrypts your private information using its private key.
  4. All such programs should make it easy for users to have their password sent to them encrypted via a supplied public key. (I.e. tell the user where to go to get crypto software to make their own key, and then allow the user to provide a public key (perhaps even store it in their profile) and use it to encrypt password reminders, etc., when necessary. The same techniques should be used to handle “secret question” transactions and the like (obviously).

Correction: as Andrew, my loyal reader, points out — servers shouldn’t store passwords at all. The server should store the hash, and for login attempts the server should ideally provide “salt” which should be added to the hashed password and encrypted before sending. Then, a hacker probably can’t “replay” the encrypted/hashed username/password combination to break in (since they won’t usually be able to enter the session which had that particular salt). Even if the server is totally compromised, no cleartext passwords are stored in the system. It follows that users can never have their old passwords sent to them, they can only be given an opportunity to reset their passwords. If a web service offers to send your password to you, avoid it if you can and treat it as utterly insecure otherwise.

The problem is that, in the end, the password restoration process is only as secure as email, so while the server shouldn’t store passwords and should allow resets instead of sending old passwords, ultimately you’ll need some mechanism to restore access, and if it goes over email we’re back to hopeless insecurity.

Steps one to three, of course, are essentially what https does (but only applied to sensitive data, rather than the whole web page), but has a number of added benefits. It allows reasonable levels of security on commodity http servers. And it will make https even more secure, since https is currently a single point of failure. Here are random hackers discussing methods for cracking or spoofing https. (Do you think your local Savings and Loan or Credit Union paid to have any additional security beyond https for its online banking software?) And it will give criminals headaches in trying to deal with a bizarre cornucopia of — possibly layered — security protocols. (It’s better to have ten different and not entirely reliable layers of security than one that you’re convinced is incredibly good — even if it is incredibly good.)

If nothing else, it’s a competitive advantage. After all, no security is impregnable — the trick is to be secure enough that would-be hackers pick an easier target.