Open Letter to LiveJournal – Please protect my password :(

Dear LiveJournal, caries

It would appear that you are storing an md5 hash of each user’s password in your database. Although I certainly could be wrong, I have reason to believe this is your method (see below), and it worries me greatly. I am concerned that my password and the passwords of all other LiveJournal users are highly vulnerable to attack. In this day and age, this method is almost no different than simply storing my password in plaintext.

To reiterate what many of you probably know, the original purpose of storing an MD5 hash over plaintext is that the passwords would ideally be unrecoverable even in the event that an attacker was able to obtain a copy of your database. This security is needed because such attacks do happen successfully even to companies that take network security seriously.

With advances in hash-table attacks (eg: “Rainbow Crack“), it is conceivable that any attacker capable of obtaining your database would have no trouble whatsoever converting all of these hashes to their original passwords in a short amount of time with even very basic computing equipment.

I appreciate your efforts to not send passwords in cleartext even on non-encrypted connections. This is above and beyond the usual call of duty, however, the storage method is antiquated and no longer safe.

It would be rude for me to bring up the problem and just leave you hanging, so I will humbly make a recommendation: store the passwords using a salt that is randomly generated (by mt_rand(), not rand()) for each user, and then hashing the salt and password using a more secure method of hashing such as bcrypt. I will include references that explain the reasons for each of these choices.

LiveJournal has always been very proactive in adopting or even creating new technology to take care of serious issues like openness, scalability, and even security. I realize that many other large sites may be guilty of this oversight also, but that doesn’t make your users any safer. Please address this issue as soon as is healthily possible. I – and I’m sure, others – would be more than willing to provide more info if that would help you make the conversion even faster.

If I was wrong about how you are storing passwords, please correct me so that I can clear the air (and apologize profusely).

Thank you for your time,
– Sean Colombo

PS: Thanks for memcached, it makes running my own sites much more cost-effective.

EXTRA INFO:

  • Everyone is doing it… but they’re doing it wrong.
  • Since LJ uses PHP, please generate the random salts with mt_rand() instead of rand(). I don’t mean to patronize you if you already know about mt_rand, I’m just trying to cover all bases here.
  • More info than you’d ever want to know about securely storing passwords
  • A really solid implementation of using Rainbow Tables to crack md5 hashes: Ophcrack.
  • For the curious: my indication that the passwords are stored as a simple md5-hash comes from the code used to encrypt the password before sending it to the LiveJournal login code. This is extremely nice that they do this, but its aim is to protect against sniffing out packets to find your password. At the same time, a site like LiveJournal has a nice juicy database full of millions of tasty passwords… enough to entice an attacker to steal the whole thing and steal millions of identities instead of victimizing individual users, thus creating a much bigger problem.

    LJ sends out a ‘challenge’ with the login form. This challenge (chal) is combined with your password (pass) as follows before being sent (in ‘res’) to LiveJournal:
    var res = MD5(chal + MD5(pass));
    What this implies is that LJ has an md5 hash of each user’s password, which they then combine with the challenge you send them and compare against your response. This is a good zero-knowledge proof that you know your password (or at least its md5 hash). This “extra security” while well-intentioned, actually means that an attacker could log into your LiveJournal account using your hash even before cracking it… but this is a very small problem since the main reason we care about the way a password is stored is that you probably also use your password for other (possibly sensitive) accounts (such as your online-banking/paypal/etc.).

UPDATE: I thought I’d wait to get some verification that I was right that they store the passwords like this before bugging LJ, but I’d want someone to report things like this to me ASAP if one of my sites had a problem… so I sent this along to them now (as a support ticket on LiveJournal). I’ll update if they get back to me.

UPDATE: Remembered LiveJournal is open source… started browsing the code. Found out it’s perl, not PHP (oops).

UPDATE: This keeps getting worse. It turns out they store the passwords as plaintext! see the comments below for more info.

11 thoughts on “Open Letter to LiveJournal – Please protect my password :(

  1. Note: I have not looked at the livejournal code

    I wouldn’t go so far as to say they could hack into an account using just the knowledge of the password MD5. Hopefully the challenge is combined in some way with some privileged information (like a randomly generated number) as well as some known information (such as the user’s IP, or Mac Address) which when hashed together and sent back can be re-verified upon receipt and confirmed with the sender’s information. (Yes, I hear you naysayers complaining that they could spoof the IP and such… but any significantly determined attacker will eventually find a way into your system. I’m just assuming not all attackers are that determined.)

    However, I would agree that it seems pretty obvious that the password is stored as an MD5 hash _somewhere_.

    While bcrypt is cool and and provides one with a way to scale up crypt complexity with ever increasing computing power I wonder if it’s really necessary. Your suggestion about the simple salted hash is the best option in my humble opinion. Just create a random salt for every user, store it in the database, and use it as part of your hash.

    Even though a hacker stealing the database would be able to reproduce rainbow tables a few simple facts reveal themselves:

    1) A full set of rainbow tables may take hours to days to generate (currently)
    2) A new set of rainbow tables is necessary for each user’s password
    3) At that point scamming the password off users directly is likely much easier to do.

    Then again with parallel computers and hardware MD5 implementations the generation time can be cut down significantly.

    In the end it’s probably best to plan for the future. I’ll give the Facebook team the benefit of the doubt (yeah I know… I’m an optimist) and assume that they have something in place to protect my useless data.

    This is why I use a different password for every login I have.

  2. Being that I was responding to this in Facebook at first, I accidentally typed “Facebook team” in place of “Livejournal team”. Hopefully you knew what I meant.

  3. @Joe

    I wouldn’t go so far as to say they could hack into an account using just the knowledge of the password MD5.

    I would :)… their challenge is just sent in the login form and is not special. The system you outlined is cool, but they don’t do anything fancy like this. The way I’m so sure is that I wrote a tool to login to LiveJournal through PHP as part of my soon-to-be-announced open-source project: SiloSync. Gimme your hash & I’ll demonstrate! :-D

    Your suggestion about the simple salted hash is the best option in my humble opinion. Just create a random salt for every user, store it in the database, and use it as part of your hash.

    After reading the rest of your post, I see what you mean. That would certainly be reasonable, especially if it was hard to cram bcrypt into your code-base.

    This is why I use a different password for every login I have.

    You’re smart. Dang that’s hard though, I think I only have 7 regularly used passwords & I consider myself fairly paranoid.

  4. It does seem that they’d have to be storing the passwords as unsalted MD5 hashes. I’m downloading the LJ code now so that I can grep around in it. I don’t know perl, but I can fake it. ;-)

    Joe: If the password hashes aren’t salted, you only have to generate the rainbow tables once in order to recover any number of passwords. The point of salting is that a cracker would have to generate a set of tables for each individual salt in the database. Alternatively, one could use a reduction function which accounts for the combined length of both the password and the salt when generating tables, but this would be computationally prohibitive for all but the shortest salts.

  5. @Sean

    Yeah, keeping so many passwords seems difficult until you have a single secure login for your desktop which manages your password list for you.

    Examples would be
    GPass – The Gnome Password Manager
    KWallet – The KDE Wallet Management System

    As you well know, I’m a bit odd in that I refuse to sign up for any service that I won’t use all the time, so I only have 8 passwords to remember. 7 Individual important passwords, and one “this password sucks and if it is compromised I don’t care because it’s only used on sites I could care less about” password.

    I’m really glad you’re moving on SiloSync, it’s going to be an invaluable tool in the days to come. I’m going to go home and make my blog SiloSync ready ASAP.

  6. It’s worse than you suspected. They’re storing the passwords in plaintext.

    From cgi-bin/ljlib.pl:


    # Validate password
    my $hashed = Digest::MD5::md5_hex($chal . Digest::MD5::md5_hex($pass));
    if ($hashed eq $res) {
    return 1;
    } else {
    LJ::handle_bad_login($u);
    return 0;
    }

    You may want to make a post in the lj_dev community about this.

  7. @Joe great advice! Windows users might want to look at Bruce Schneier’s Password Safe.

    @Chris w0w! Well that’s a whole lot worse than expected. I posted to lj_dev (thanks for the link), hopefully we can get someone at LJ to pay attention to this

  8. @Chris
    Nice detective work!
    With a hashed password the worst you have to look out for is hackers… with plain text you have to worry about potential disgruntled employees as well.

    Awesome.

    @Sean
    The age of the digital wallet has come.
    With all the passwords I’m collecting in mine I’ll likely be the first person to get lower back pain from a digital wallet.

  9. I think your problem starts at and is bounded by using the same password on multiple sites, especially when you don’t (shouldn’t) trust the site owners.

  10. Pingback: SeanColombo.com » Pitt talk was fun

  11. Интересная статья. Главное – полезная инфа. Спасибо большое за оригинальную статью!

Leave a Reply

Your email address will not be published. Required fields are marked *