Why No One Should Use LastPass

Update: LastPass told me that they have never been asked by the government to silently downgrade a hash. Also URLs are unencrypted for use with bookmarklets. This has been fixed in version 2.5.4. So update LastPass plug-in to at least version 2.5.4 (sorry FireFox and IE your still stuck on 2.5.0 as of 9/10/2013).

Update (11/7/2013): LastPass just alerted me to the fact that 3.0 is out for all browsers. So this fixed for all browsers. Also I'm pretty sure that all the smart phone apps have been updated.

They refuse to fix a vulnerability. I guess I don't need to say more, but here you go. They originally thought that SHA256 is a good way to turn a password in to an encryption key. They put out videos that say eight character random passwords of upper, lower, and digits is secure. About two years ago, I anonymously reported a bug that the LastPass server can ask for a double SHA256 of a password during login. Along with a few minor bugs about checks being done only on the client side (these got fixed). I reported the double SHA256 bug again a year and a half ago and again a year ago. Then a half year ago in the middle of my speech on password hashing fails I had a PSA on not using LastPass (wow I forgot how bad I am at speeches). The problem with this is a single HD7970 GPU should be able to get over 350 MH/s.

You should note that LastPass is a US company. I try to think highly of my government but then shit like this happens. Sometime before May 2th, I wanted to tweet "If I were the #FBI I'd ask @LastPass for double SHA256s (possible during login) of users that have credentials for certain domains.", but I didn't want to look crazy. Then news of PRISM came out. Hmm not too crazy after all (just like all the other nuts :)).

The current state

  1. The user can get this error during login:
    <response><error iterations="1" /></response>

    Then the client will calculate and send sha256(sha256_hex(email + password) + password). Then the server just sends the correct number of iterations:
    <response><error iterations="5000" /></response>

    Then the client will calculate and send the correct value and all of that happens without the user knowing anything out of the ordinary happened. Well beside that it took twice as long to login.
  2. Here's the important form data sent when adding a new site:
    name:!zTV1xfF8uKjuJH1sUwDctA==|gQ+TBtD1JZS9X28fL9VQog==
    grouping:!Sjz4qFbyBxZEDITi6bvjxw==|fLvHxEC6x3KDX7W8rX1wOA==
    url:617364662e636f6d
    username:!E3jSnQLNrvhgUyNKMO1IXA==|bYrKihIbgw9zgN+BEF6Drg==
    password:!s2VUiEvz45xyWZZoqpQv0Q==|NCR52+NBUfJ8EVE/CRqHwA==
    extra:!RMYdIMV0vy9XxmxyF2qz7g==|ZlUu2LfyWJ5ta/YdwSuAQg==

    Note that their encrypted data looks like this "!IV|DATA"

    unhex(617364662e636f6d) = asdf.com
  3. If you log into LastPass through their web site (which is a dumb idea since they can then steal your plaintext password) it sends the old method (double SHA256) first then gets an error.
  4. Default number of PBKDF2 rounds is now 5000. I doubt that is because of me. This number is still low since it should be doubled every two years (so 64000 should see speeds of 8400 H/s/GPU (GPU = 7970)). 5000 is 10 times better than it was and 64000 rounds probably takes a long time for slow clients. So it is "good enough" if you have a really strong password. PBKDF2-SHA256 with 5000 rounds should see speeds just over 100000 H/s/GPU (GPU = 7970).
If you want to implement this into a password cracker here's an example hash:
Email: test@test.com
Password: password
Hash: d5870f0c715312d3cb559274ca998f9b733f079cf89c24791533b599fe83814d

d5870f0c715312d3cb559274ca998f9b733f079cf89c24791533b599fe83814d = sha256("test@test.compassword")
dc1095cace78acffb66140cbc4d43b12f69299ecfee51f7034ebfea4dec6a9db = sha256("d5870f0c715312d3cb559274ca998f9b733f079cf89c24791533b599fe83814dpassword")

You can generate others by going to the sign in page at lastpass.com, open a console (Chrome: Ctrl+Shift+J, FireFox: Ctrl+Shift+K), and entering this:
make_lp_hash_iterations(make_lp_key_iterations("test@test.com", "password", 1), "password", 1);

Email to security at lastpass dot com (09-19-2012 02:45 PM)

When you log in it sends sha256(sha256(email + password) + password) and gets an error that has the correct iteration count. Then sends pbkdf2_sha256(pbkdf2_sha256(password, email, iterationCount, 32), password, 1, 32).

The correct way to do this is to ask for the iteration count and then send the correctly iterated hash.

The plug-ins/apps should store the last known iteration count and should warn the user if the iteration count is lower than the last known. This will decrease your ability to pull a HushMail on the iteration count.

-------

I think it is irresponsible to tell your users the recommended iteration count is 500. When 12 years ago, PBKDF2 had a recommended minimum iteration count of 1000.

-------

Also is there a reason you store unencrypted URLs?

The reply (09-19-2012 04:00 PM)

Thanks Steve,

Comments below.


On Wed, Sep 19, 2012 at 3:45 PM, Steve Thomas <steve at tobtu dot com> wrote:
> When you log in it sends sha256(sha256(email + password) + password) and gets an error that has the correct iteration count. Then sends pbkdf2_sha256(pbkdf2_sha256(password, email, iterationCount, 32), password, 1, 32).
>
> The correct way to do this is to ask for the iteration count and then send the correctly iterated hash.
I thought in the various plugins, we began to send the default # of iterations (500) first and then reissue with the request with an updated iteration count (possibly lower). I will create an internal CR to make sure we do it that way everywhere.

> The plug-ins/apps should store the last known iteration count and should warn the user if the iteration count is lower than the last known. This will decrease your ability to pull a HushMail on the iteration count.
We do cache the iteration count in the extension. We will consider warning the user if lower.

> -------
>
> I think it is irresponsible to tell your users the recommended iteration count is 500. When 12 years ago, PBKDF2 had a recommended minimum iteration count of 1000.
There is obviously a trade-off here -- we tested how long it would take on various phones, platforms and technology (people access us using everything -- old phones, old IE versions where the javascript engine is slow, etc) and decided that the time it took to login with 500 iterations was a good tradeoff between speed (it could easily take > 2 seconds on some phones) and security. We also exposed the setting to the user so they can increase it if they wish. Finally, we made it easily configurable by us so as the hardware improves, we can increase the default.

> -------
>
> Also is there a reason you store unencrypted URLs?
The only reason is so we can show favicons for each of your sites.