Hold my beer and watch this!

Firefox – Down on it’s knees

My laptop slowed dramatically the last few weeks, especially Firefox. Rebooting didn’t help. I suspected a virus, but it was clean. I cleared some Windows caches that can slow things down, but that didn’t help either.

Going through the process list, I noticed that Firefox was using a huge amount of memory, and was adding to it by the second. So it was off to The Google to see what the deal was.

The “download history cache.” Clean out the friggin’ “download history cache.”

All is good again.

Posted: May 4th, 2009 | Filed under: Coding | Tags: , , , | 1 Comment »

Password Security – Protecting your user base

You know how to protect your own password; how do you protect your user’s passwords?

It is well understood that you should use a different password for each secure site you visit. Given the routine use of email addresses as logins, using a single “universal password” turns a successful attack on one of your accounts into access to all of them.

Not good.

On the other side, if you run a secure site, you need to protect your users, in case they don’t know this, and are not as careful as they should be. (And many of them won’t be…)

This was brought home a few years ago, when I had a project that required me to hack the passwords to my client’s web site. We were moving their site to a platform with incompatible password support, and their user’s passwords were (properly) encrypted, so we couldn’t move the password file directly.

There were many ways to approach this problem, but we wanted to make it as invisible as possible. So, as part of this effort, I put together a quick crack program to see how many of the passwords we could discover ourselves.

We ran the program for a couple of weeks and cracked around 25% of the passwords through a combination of dictionary and brute force attacks. What’s worse, most of these passwords broke the first day.

Why were these passwords so easy to break?

Two reasons:

  • Bad passwords, and
  • Easy to crack password protection.

The bad passwords were: words from the dictionary, common passwords (”asdf”, “abc123″), easily broken through brute force (”a”, “aa”), or default passwords that were never changed.

The weakness of the password protection wasn’t as obvious, as they’d used the conventional approach of storing a secure hash of the password. Checking passwords was accomplished by hashing the password and comparing the hash value with the stored hash. If they match, you can assume the password was correct.

The problem with this, however, is that the hash value is the same for every account using that password. To understand why this is a problem, let’s look at the design of the crack program I wrote.

The attack worked by constructing a hash table of every unique password hash. It then hashed trial passwords and did a single hash table look up to see if that password matched one used by any of the users. This approach wouldn’t have worked, however, had an effort been made to ensure that the hashed password values would always be unique.

An easy way to create unique hash values would be to calculate the hash of a combination of the user name and password. Now, the crack program wouldn’t be able to do a single test for the hashed value of password “abc123″, it would have to calculate a separate hash value for each user name.

In our case, with over 30,000 users, the crack program would have taken 30,000 times longer to run! We still would have been able to do the dictionary part of the attack, which ran in about a minute, but the brute-force part would have been out of the question. Even still, the dictionary attack would have taken several weeks to complete.

How do you protect your user base?

  • Require reasonable passwords,
  • Ensure that password hashes are unique, and
  • Make your users change default passwords.

(And don’t count on being able to crack your password file…)

Posted: March 8th, 2009 | Filed under: Coding, Privacy | Tags: , , , | No Comments »

Easy PHP Cookies

I was working on a security subsystem for a website the other day, and I needed to encode a bunch of variables into a cookie. I’ve written this kind of code way too many times before, and it’s pretty straightforward. It is very tedious, however, and can get complicated if you have to worry about escaping characters, encoding arrays, etc.

With this in mind, I decided to sniff around in the PHP documentation and see if there was something there that I could use to make this easier. I started looking at serialization, followed a few references, and pretty soon I came up with a very simple solution:


// Encode the values and set a cookie
function encode_cookie ($foo, $bar, $snork)
{
    $cookie = serialize(compact("foo", "bar", "snork"));
    setcookie("name", $cookie, 0, "/", "ericwinkelman.com");
}

// Get the cookie, and decode the values
function decode_cookie (&$foo, &$bar, &$snork)
{
    extract(unserialize($_COOKIE["name"]));
}

The key to this code is the compact and extract functions. These functions work directly with the program’s symbol table, and not the variables themselves. The compact function takes the names of the variables to store in the cookie, and looks up the values in the symbol table. Similarly, the extract function gets the variable names and values from the cookie, and updates the symbol table with this information.

Through these functions, you don’t have to worry about formating, parsing, escaping, variable orders, etc. It even works with arrays. You must, however, make sure that the names of the function parameters are the same between the encode_cookie and decode_cookie functions.

For extra credit, I suggest encrypting the cookie value so that site visitors can’t mess around with them. Michael Gracie recently posted encryption and decryption functions that can be used for this.

Bake at 450 for 10 minutes and cool slightly before serving…

Posted: February 18th, 2009 | Filed under: Coding | Tags: , | No Comments »

OpenSSL and RSA Keys – Building strong keys

Recently, I was reviewing the number theory associated with RSA Public Key Encryption. (I know, I need to get a life.) I noticed that there were several precautions listed for selecting the primes used to generate these keys:

  1. p and q should differ in length by a few digits
  2. Both p – 1 and q – 1 should contain large prime factors
  3. gcd(p – 1, q – 1) should be small

([Den84] Dorothy Denning. Cryptography and Data Security. Addison-Wesley, 1984. )

While precaution 1 can be checked by observation, precautions 2 and 3 are met by picking your primes in particular ways.  (To be discussed some time in the future, assuming I don’t get a life before then…)

Nerd that I am, I fired up OpenSSL and took a look at some keys. What I found was that all of the keys failed test 1, some of them badly.

For example, this command will create a 2048 bit RSA key, and display it on the terminal:

openssl genrsa -3 2048 | openssl rsa -text –noout

Parsing through the output, you’ll find the two primes used to create the key:

[stuff removed]
prime1:
00:df:5f:81:5b:54:38:20:a4:bb:11:62:1f:05:33:
e2:68:27:f3:25:c9:2b:f9:75:5c:75:10:c0:70:67:
99:6b:9d:2c:99:5d:3a:1e:3a:ff:7e:dc:65:6a:a2:
09:44:0f:b8:10:43:b6:66:15:05:da:52:7b:79:a7:
79:d5:d7:84:01:c8:84:d2:76:0b:80:4b:3d:68:28:
d6:3c:f2:e6:02:27:11:f8:e8:52:ef:f3:5a:79:d9:
89:1f:fb:4b:fd:63:c9:fb:da:97:0f:e4:36:95:73:
a0:53:bf:cf:e8:a6:e0:7e:86:7e:23:14:a8:82:bb:
5f:7a:3e:14:a5:c2:7c:8c:eb
prime2:
00:df:46:72:0f:05:aa:b3:33:3b:e8:57:c7:40:43:
e8:42:0c:00:5e:a5:48:cc:48:76:3b:bd:8a:a5:29:
55:a5:17:0b:a7:e8:65:55:43:e0:22:63:13:33:87:
b6:45:0a:77:70:54:d2:be:c6:d8:41:22:8f:d6:19:
40:95:7f:7e:cc:75:c6:7f:80:bd:89:ab:d4:b7:69:
9f:73:2b:53:12:4b:14:ff:b3:b4:b6:c1:c2:88:f2:
34:d7:c7:34:2c:2f:86:9a:12:41:22:53:2c:2e:1e:
f4:37:d7:51:d5:cf:6e:bd:3b:0c:ac:10:1b:76:5a:
88:52:fa:10:61:9b:6e:a4:89
[more stuff removed]

Note that in this example, the two primes are the same length, and have the same prefix:

00:df:

I repeated the test a number of times, with similar results; the lengths were always roughly the same (within a bit or two) though the values of the generated primes generally differed by more than above.

I can’t speak to precautions 2 and 3, as I haven’t read the key generating code, and don’t know how they go about picking their primes. (Anybody out there familiar with this?)

Given the size of the key, this probably isn’t a big concern for most applications. If you are restricted to smaller keys, however, you may want to generate a few keys, and select one with a significant difference between the values of the primes.

Conclusion: OpenSSL can generate keys that violate precaution 1.  I don’t know yet about conditions 2 and 3, but I think it is unlikely that either of them are met.

Posted: January 30th, 2009 | Filed under: Coding, Privacy | Tags: , , , , | No Comments »

Setting the bar too low

Like many nerds, I was amused by The Google’s motto: “don’t be evil”. It had a nice David vs Goliath image, and made a point about Microsoft’s evil empire.

But David has grown up. Between The Google’s user knowledge, and their extensive data mining abilities, they are capable of doing terrible things.

“Don’t be evil” sets the bar way too low.

Posted: January 22nd, 2009 | Filed under: Coding, Privacy | Tags: , , | No Comments »