haggholm: (Default)

Mail encryption

If privacy of your email matters to you, you may want to consider using end-to-end encryption. This is different from using a “secure” email provider: With end-to-end encryption, the sender of the email encrypts it before sending, and the receiver decrypts it after receiving it. It's not decrypted during transit—thus, even your email provider cannot read your email.

Without going into mathematics whose details I’d have to review anyway, suffice to say that PGP is a strong system of email security that, with sensible (default!) settings, cannot be effectively broken with modern technology and modern mathematics.¹ (Strong enough, in fact, that various US security agencies tried to suppress it, and when its creator released it for free to the world, he was taken to court and accused of exporting munitions. The case never really went anywhere.)

PGP uses something called asymmetric encryption. Technical details aside, the nifty and amazing thing about it is it’s what’s known as a public key cryptosystem, meaning that I can give you a bit of password (public) key that you can use to encrypt messages for me, but no one², not even you, can decrypt them…except for me, as I retain a special (private) key with the unique power to decrypt. My public key is here, should you wish to send me secure email.

My preferred solution is a plugin called Enigmail for my mail client of choice, Thunderbird.

PGP with Enigmail in Windows

There are some other solutions, none of which I have used.

PGP for webmail (like GMail) in Chrome

There's a browser plugin, currently for Chrome only though Firefox is in the works, called Mailvelope that will transparently encrypt/decrypt your webmail. There's a helpful guide. For now, there’s another plugin for Firefox, but it has received mixed reviews.

Linux

If you’re using Linux, this shouldn’t be a problem in the first place. Install your mail client of choice and it surely comes with or has an OpenPGP plugin readily available.

Other

Apparently there's an Outlook plugin. There’s a plugin for OS X Mail.app.

Passwords

As a reminder, keep in mind that your security is never stronger than your password; and your password is never safer than the least secure place it is stored. If your password is weak (password, your name, your date of birth…) there’s no helping you. If your password is pretty strong (|%G7j>uT^|:_Z5-F), then that’s no help at all if you used it on LinkedIn when they were hacked and their password database stolen, so that any malicious hacker can just download a database of email addresses paired with their passwords.

The solution is to use strong passwords, and to only use each password in one place—if you steal my LinkedIn password you can hack my LinkedIn account, but you can’t use that password to access my bank, email, blog, or any other account. The drawback of strong, single-use passwords is that you’ll never, ever remember them. The counter is to use software to remember them for you.

My preferred solution is a family of software called KeePass for Windows, KeePassX for Linux, KeePassDroid for Android (my smartphone), and so on. This has the primary feature of storing all my passwords in a very strongly encrypted file. I store this file in Dropbox, which lets me share it between my devices (work computer, home computer, laptop, phone). I don’t consider Dropbox fully trustworthy, but that’s OK: if anyone breaks into my Dropbox account, all they’ll get is a very strongly encrypted archive that requires either major breakthroughs or billions of years to break into (or a side-channel attack like reading over my shoulder, literally or electronically; but if they can do that my passwords don’t matter anyway). Thanks to this, I can use very strong passwords (like -?YhS\[q@V4#]F'/L|#*1z)_S".35/#T), uniquely per website or other service. Meanwhile, I only have to remember one password: the password for KeePass itself (which I shouldn’t use for anything else).

The KeePass family of software also tend to come with good password generators, which can generate garbled gobbledygook like the above, and/or include constraints if a given website won’t let you use special characters (e.g. you can tell it to generate a random password 10 characters long with letters and digits but nothing else, which includes at least one letter and one digit). You can also use it to store files, which is a nice way to keep track of things like PGP keys.


¹ It may be broken in the future if usefully sized quantum computers are ever build or if a major mathematical breakthrough is made in prime factorisation—mathematicians have failed to make this breakthrough for some centuries now. If this happens, then I still wouldn’t worry about my personal email: the communications of major world governments, militaries, and corporations will become as vulnerable as mine, and will be a lot more interesting.

² That is to say, there are no direct attacks known to be effective against the ciphers used. There are side channel attacks, which is a fancy way of saying that someone could break your encryption without defeating the mechanism. For example, they could be reading over your shoulder, or they could install malware on your computer that records keystrokes (when you type in passwords), or they could beat you with a $5 wrench until you talk.

haggholm: (Default)

In a spectacular display of missing the point, a group of “security researchers” released a Firefox plugin called BlackSheep, designed to combat Firesheep by detecting if it’s in use on a network and, if so, warning the user.

To explain why this is at best pointless and at worst harmful, let’s recapitulate what Firesheep does: By listening to unencrypted traffic on a network (e.g. an unsecured wireless network), it steals authentication cookies and makes it trivial to hijack sessions on social networks like Facebook.

Let’s use an analogy. Suppose some auto makers, Fnord and eHonda and so on, were to release a bunch of remote controls that could be used to unlock their cars and start the engines. Suppose, furthermore, that these remote controls were very poorly designed: Anyone who can listen to the remote control signals can copy them and use them to steal your car. This takes a bit of technical know-how, but it’s not exactly hard, and it means that anyone with a bit of know-how and a bit of malice can hang around the parking lot, wait for you to use your remote, and then steal your car while you’re in the shop.

Now suppose a bunch of guys come along and say Hey, that’s terrible, we need to show people how dangerous this situation is, and they start giving away a device for free that allows anyone to listen to remotes and steal cars. What this device is to Fnord and eHonda remotes is exactly what Firesheep is to Facebook, Twitter, and so forth. What’s important to realise is that the device is not the problem. It does allow the average schmoe, or incompetent prankster, to steal your car (or use your Facebook account), but the very important point is that the car thieves already knew how to do this. Firesheep didn’t create a problem, but by making it trivial for anyone to exploit the problem, they generated a lot of press for the problem.

What the Firesheep guys wanted to accomplish was for Facebook and Twitter and so on to stand up and, in essence, say Whoops, we clearly need to make better remote controls for our cars. (It’s actually much easier for them than for our imaginary auto manufacturers, though.) True, Firesheep does expose users to pranksters who would not otherwise have known how to do this, but the flaw was already trivial to exploit by savvy attackers, which means that people who maliciously wanted to use your account to spam and so forth could already do so.

Now along come the BlackSheep guys and say, Hey, that’s terrible, the Firesheep guys are giving away a remote that lets people steal other people’s cars!, and create a detection device to stop this horrible abuse. But of course that doesn’t address the real point at all, because the real point has nothing to do with using Firesheep maliciously, but to illustrate how easy it was to attack a flawed system.

This is stupid for several reasons:

  1. If BlackSheep gets press, it might create an impression that the problem is solved. It isn’t, of course, firstly because Firesheep wasn’t the problem to begin with, and secondly because BlackSheep only runs in, and protects, Firefox.

  2. People running badly protected websites like Facebook could use BlackSheep as an excuse not to solve the real problem, by pretending that Firesheep was the problem and that problem has been solved.

  3. Even as a stop-gap measure, BlackSheep is a bad solution. The right solution is for Facebook and Twitter and so on to force secure connection. Meanwhile, as a stop-gap solution, the consumer can install plugins like the EFF’s HTTPS Everywhere that forces secure connections even to sites that don’t do it automatically. This is a superior solution: BlackSheep tells you when someone’s eavesdropping on you; HTTPS Everywhere prevents people from eavesdropping in the first place.

    Let me restate this, because I think it’s important: BlackSheep is meaningful only to people with sufficient awareness of the problem to install software to combat it. To such people, it’s an inferior solution. The correct solution is not to ask consumers to do anything, but for service providers (Facebook, Twitter, …) to fix the problem on their end; but if a consumer does anything, BlackSheep shouldn’t be it.

As I write this post, I hope that BlackSheep will get no serious press beyond a mention on Slashdot. It deserves to be forgotten and ignored. In case it isn’t ignored, though, there need to be mentions in the blogosphere of how misguided it seems.

Let’s all hope that Facebook, Twitter, and others get their act together; meanwhile install HTTPS Everywhere.

haggholm: (Default)

Short version: Facebook sucks, Twitter kind of sucks, and if you use Firefox, install this add-on now.

Long version:

A Firefox extension called Firesheep made the news recently in a pretty big way. In a nutshell, it’s a Firefox addon that allows just about anyone to walk into, say, a coffee shop with an open wireless network and capture the cookies¹ authenticating everyone in there with Facebook. Or Twitter. Or…well, any of a great number of sites where you probably don’t want just about anyone to read everything you or your friends have posted, or pose as you.

Of course, Firesheep didn’t create this problem. What it did—and what it was designed to do—was to highlight the problem by creating a tool so easy to use that anyone could do it. Malicious hackers who actually want to steal your credentials and do evil things with your accounts could already do it. The Firesheep people wanted to give the problem more press, and they succeeded. It’s as if all car alarms had an easy way to disable them that the car thieves already knew; Firesheep gave it publicity by selling a simple toolkit to average consumers. (It’s also not, strictly speaking, limited to wireless networks, but open wireless networks are a huge opportunity.)

I won’t go into the technical details in great depth at this point. Suffice to say that you can connect to many servers, including all these big social network, in a secure way. The problem is that it’s not the default. Use a secure SSL connection (you’ll recognise it by the https:// in the URI) and this particular problem goes away.

If you happen to use Firefox, there are actually plugins that you can install that force the browser to use the secure versions of various websites. You can look up ForceTLS on your own time if you are so inclined. I will personally go with HTTPS Everywhere, published by the EFF. Simply install it, and Firefox will connect to Facebook, Twitter, &c. in a way that cannot be eavesdropped upon.

Of course, it has limitations; see the FAQ. Ironically, LiveJournal is an example of a site that doesn’t actually work because it doesn’t really have a secure version.


The real, long-term solution is obvious to anyone who understands the problem and knows anything about authoring websites: No credentials should ever be transmitted over unencrypted channels (except such credentials as are specifically intended for it, like the Diffie-Hellman handshake and what not). If you ever write a webapp with authentication, only allow authentication over SSL, and only send the cookie over SSL. If you’re worried that it’ll be too bandwidth or CPU intensive, by all means serve static content—anything that you explicitly, whitelist-wise know to not matter in terms of security—over plain HTTP, just on a different subdomain or domain or what have you than the one on which you serve the cookies. (There are other reasons, anyway; my own website already serves static content from a separate subdomain because caching rules are very different, and static content can be served up by Lighttpd rather than an Apache instance that runs everything through mod_wsgi and Django.)

Unfortunately, this is not a solution that the client can effect: It’s up to website and service authors. As a user, the best you can do is stick to SSL whenever possible.


¹ The cookies, not the credentials. Even a site with unsecure cookies may transmit passwords securely. Conversely, even if you login through a secure https:// login page, the cookies may be served up for anyone to sniff and steal.

haggholm: (Default)

From this story, Strong Passwords Not As Good As You Think, by some commenter called Rob the Bold:

According to the article (cited by the citation):"Users are frequently reminded of the risks: the popular press often reports on the dangers of ïnancial fraud and identity theft, and most ïnancial institutions have security sections on their web-sites which oïer advice on detecting fraud and good password practices. As to password practices traditionally users have been advised to . . . "

-Choose strong passwords

-Change their passwords frequently

-Never write their passwords down

I would suggest that this is a case for the popular quip: "Pick two".

Personally, I can’t be arsed to change passwords frequently, which makes unique passwords all the more important: Since I rarely change them, I need to make sure that if somebody steals all the passwords from site A, that doesn’t compromise my accounts on sites B through Z. Have I plugged SuperGenPass lately?

haggholm: (Default)

This seems to be an oddly neglected topic on which I can’t find much useful information: How do you secure your application’s credentials? I don’t mean user credentials—you can find any number of articles detailing why secure hashes salted with nonces is the only way to go, and so on. I mean something more fundamental: My application sits on a server somewhere, on a shared server to be specific, and it has to connect to the database where all these deliciously salted and secure passwords are stored. All the user authentication in the world won’t save me if anybody with an account on the same server can access the config files where the application’s own credentials are stored, and since that file has to be readable by the webserver (user apache or group www-data or whatever the local case may be), odds are that this is indeed possible.

I realise that this is, of course, highly dependent on the environment. My own environment of interest is a Linux server running apache 2.0.52 (or so) with a custom Python framework running on mod_wsgi. I am primarily curious about people’s solutions within that sort of context, but I am also generally curious: How do you manage your application credentials?

haggholm: (Default)

I’m pretty bad at password management. I don’t have a great memory for complicated strings of random characters—in fact I don’t have a great memory at all. In very rough terms, I use a set of passwords like

  1. A secure “standard” password for sites and services I trust (with some minor variations)
  2. A modified, more complicated version of the above for root passwords etc.
  3. A different password for desktop and laptop user login (…these should be different)
  4. My old “standard” password, now demoted to use on sites I don’t really trust to store my password securely
  5. A throw-away password (this one’s actually a dictionary word!) for untrusted services where I don’t care if they get hacked but where I need a password to use them

This is a hell of a lot better than using “p4ssw0rd” for a password wherever I go, but I do knowingly commit a mistake shared by many: I reuse passwords all over the place, and while I try to make a rough judgement call (do the people running this site seem like the sort to store my password securely hashed and salted, or in a reversible form, or even [shudder] in plaintext?), that’s a very fallible call to make. Also, and this is very bad, I often let my browser save my passwords. That’s very dangerous. It’s a product of sheer laziness.

Of course there are lots and lots of password managers designed to create and manage sets of better passwords—there are ones for Windows, ones for Linux, ones for Mac, and a fair number of cross-platform managers. But from my point of view these all share a number of weaknesses:

  • I need to install an application on any computer where I wish to use these passwords.
  • The application needs to be cross-platform and have good usability on at least Linux and Windows.
  • Most of the time I don’t worry about programs going out of vogue or dying—by the time a project dies in the Linux world, I’ll have long since moved to another—but a password manager needs staying power, because I can’t afford to lose all my passwords.

SuperGenPass is the best password manager idea I’ve ever seen. If you’re a non-technical reader, the best advice I can give you is “go here and install it”.

For the slightly more technical reader, here’s why I like the idea so much:

  1. It’s implemented in Javascript and runs as a browser plugin. The web is where I should use a profusion of passwords, so this is where I need quick, easy access. And it certainly looks easy: Type in your master password, click the “SuperGenPass” bookmarklet button, and voilà!
  2. It uses a hash of your master password and the domain name for a password, so every domain gets a unique password.
  3. Because each domain gets a unique password, it’s relatively safe to let your browser save the passwords. The usual vulnerability inherent in saved passwords is there, of course, but you only compromise one site at a time—never the master password.
  4. If the next version of your browser breaks compatibility with the plugin, the mobile version will let you retrieve your passwords. It’s a single, plain page with embedded Javascript. I can save it on my harddrive for easy password retrieval.

I can only see two obvious security caveats, one of which is easily negotiated, one of which looks like a fundamental and inevitable limitation of the design (and of its laudable goal of user friendliness). First, the fixable one:

SuperGenPass also provides some degree of phishing protection. Suppose you receive a phishing attack—for example, an e-mail that purports to be from Amazon but is actually from a malicious hacker trying to steal your password. It sends you to a page that’s set up to look like Amazon.com and has a similar URL (say, “www.amaz0n.com”), and includes a login form. Using SuperGenPass at this malicious Web site with your master password (“cornflakes”), your generated password is “uc15yrcmqI”. Compare with the previous example: though the master password is the same and the domain name is only slightly different, SuperGenPass generates a completely different password. Even if you are fooled by the phishing attack and attempt to log in to the impostor website, you haven’t sent your real password.

That’s fine, as far as it goes, but nothing prevents the website from harvesting your master password from the password <input/> before it’s hashed, and saving it via AJAX. If they know that you’re using SuperGenPass, they can then use your master password to generate all your other passwords. That sounds alarming, but I don’t think the odds of falling victim to this very specific phishing attack are very high. Additionally, there is an easy workaround for this: You can add a salt to the bookmarklet, which is not entered into anybody’s <input/>.

The second problem is that the algorithm uses the domain name as a salt for the hash…and that’s a pretty weak salt if a determined attacker wants to use something like a rainbow table attack: The salt is known. By design, SuperGenPass cannot use nonce values (it would compromise its excellent portability). Nor does the extra salt mentioned above help you here; it’s just part of your master password. (The hacker would crack your password+salt, not just your password.) If you are worried about somebody stealing your password and running that sort of thing on it, well, you’ll want to use more than one password. It never can hurt to use a separate password for extremely important sites, such as banking and email. (Yes, email should be considered extremely important: As Jeff Atwood has pointed out, anyone who hacks into your email can gain access to almost any other service you use by using the password reset function.)

But if these are weaknesses of SuperGenPass’s security, it is still a vast improvement on using only one or a small set of passwords. If I install this and reset a few passwords, I can use the same master passwords as I do now and gain a unique password for every site I use; even in the worst-case scenario of somebody running a rainbow table attack on my passwords (and why would anyone want my data that badly?), the worst-case scenario is gaining access to one of my master passwords. Right now, when for all I know some forum could be storing that password in plaintext, the barrier of entry is abysmally low.

haggholm: (Default)

Since I’m rewriting the framework behind my website, and since the new framework has a lot more dynamic features to go with some other projects of mine (petterhaggholm.net is pretty static), security has been on my mind, especially as I will have a login system. Of course I started with the basics: Require a session token for every action; make sure the session token is nice and secure (it’s a big hash involving a random number); make the cookies HttpOnly… (HttpOnly cookies can’t be read or set with Javascript, so malicious scripts cannot steal these cookies. They are only present in request headers.)

The problem

CSRF means that cookies alone aren’t safe, however. If you write this sort of code and don’t know what CSRFs are, I recommend you read this very good article. The very brief version of a simple example:

  • Whenever you request a resource (e.g. via GET or POST, your browser checks if it has servers matching the server.
  • If the browser has any such cookies cached, it sends them in the request header (Cookie: whatever).
  • Not only pages are requested via GET; other resources, like images, are as well.
  • The browser doesn’t keep track of what tab or window the request comes from. (I’d be annoyed if it did, since I’d lose my session data if I opened the same site in a second tab, or closed and re-opened.)

Now suppose that your webapp has an action tied to a GET request (you shouldn’t), or is a PHP app that uses the $_REQUEST superglobal without checking if it is GET or POST. Maybe there’s a Delete button on a form that works by making an AJAX call (or plain form submission) to foopage.php?action=delete. What happens if I, on some entirely different website, create a page as such:

<img src="http://www.yoursite.com/images/pretty.jpg" title="A pretty picture" />
<img src="http://www.yoursite.com/foopage.php?action=delete" title="Another pretty picture" />

Well, your browser will parse the page source, and will issue a GET request for each image src in order to display all the picture. The Cookie: header will be issued with each request, because your browser will always issue that header when the request goes to the matching domain. This means that if the webapp relies solely on the cookie for authentication, it will think that you are issuing a delete command, and will happily go ahead and do whatever it is that deletion does.

My problem with the usual solution

There is a canonical solution to this problem. (Always using POST rather than GET isn’t it—that’s a good idea, but POST requests can be forged, too.) This solution is to include a unique token in every form on generated pages; so if you request a form from secureapp.com, it might contain something like

<input type="hidden" name="secure_token" value="384729348923498" />

Ideally, this token should

  1. Be unique to this form
  2. Expire in a reasonable amount of time

The advantage of this is that because this is embedded in the page, and not present in the headers, a request issued from a different page (such as with the XSRF attack described above), the information just isn’t available.

But that’s kind of a drag. For example, what if my page uses AJAX and doesn’t contain any forms? What if I have multiple tabs or windows open with the same site (as I often do, with many sites)?

I currently strike something of a compromise: A session has one such token (which isn’t nearly as good as unique tokens all over the place, but much better than none at all: It protects me against the simple cookie-based attack). I am currently working on a mechanism to generate better tokens when there are forms on the pages, but the simple token is used by default, and will probably continue to be used for AJAX requests that just don’t have forms to reference. My framework discards all POST data supplied by requests that have either a bad session key or a mismatched or missing “XSRF token”. GET variables are never used as “data”, but only as extra resource identifiers, e.g. picture.py?pic=foo.jpg.

But a single token does have serious weaknesses. If the attacker can retrieve even one page with the token embedded (e.g. via a malicious script that issues a GET request on the client’s behalf, or by stealing it from the cache, or some means that I have yet to take into consideration), the token is compromised, and we have already established that cookies are vulnerable.

An alternative?

One fairly obvious idea that occurs to me is that while it’s easy to hijack (but not steal!) cookies, and may be possible to steal the token, the information is not available simultaneously. The cookie is not visible to the attacker: This XSRF attack is based on the fact that he can make use of the cookie by tricking the client into issuing a request that will have the cookie attached, without the attacker ever needing to access it. By contrast, the token is jeopardised precisely because the attacker may see it. What I would like to do is combine the two, e.g. by requesting a hash of the cookie value and the token value.

It’s actually somewhat ironic: Normally, it is a truism in computer security that you cannot increase security by adding more data if all those data are vulnerable. Here, however, the data are vulnerable by different avenues, and what I want to do is raise the barrier by requiring an attacker to exploit both simultaneously.

Unfortunately, this idea isn’t workable in so simple a fashion, because, well, I made my cookies HttpOnly! This means I can’t use them to create hashes, no matter how nice it would be. In essence, what I want is a browser feature that doesn’t exist, where I can request a secure, one-way hash based on an otherwise unreadable cookie:

<input type="hidden" value="2487923984" hashwith="my_httponly_cookie" />

I think what I may do is set two cookies for my sessions: The primary session identifier, which remains HttpOnly to prevent anyone from stealing it; and a token cookie, included specifically for use by the page’s Javascript, AJAX requests, etc.


Internet security is a tricky and thorny issue. I find it difficult to know when I am tackling the real issues, and when I am just engaging in busywork. An awful lot of my promising ideas have turned out to be dead ends that either wouldn’t work at all (c.f. the hash above), aren’t at all secure, or just don’t add anything to the security I already have.

Thoughts?

Syndicate

RSS Atom

Most Popular Tags