

All 32mil RockYou accounts hacked. Passwords were stored in plaintext. - archon810
http://www.techcrunch.com/2009/12/14/rockyou-hacked/

======
tptacek
Note that if you store your passwords in a fast hash format like salted SHA1,
an attacker with 32MM database rows can publish a _very_ credible sample of
usernames and passwords, and leave you scrambling to explain how the breach
isn't really as bad as it looks. Not a great position to be in.

The right answers to this problem are BCrypt, SCrypt, PBKDF, or (at a minimum)
salted "stretched" SHA1, iterated many thousands of times.

~~~
paulgb
Does using a unique salt for each user help here? Is there a non-obvious
reason why that approach is bad?

~~~
tptacek
The "salt" --- which, so far as I can tell, is a term used almost never in
academic crypto research --- defeats one very effective exotic attack: the
"rainbow table", where an attacker builds a database of perfect hash :: string
correspondances.

But too many people forget that before the popular Windows cracking tools were
released, passwords were cracked exclusively by tools like JtR, which simply
contain highly optimized loops for brute forcing passwords. "Salts" do nothing
to slow this attack down, because they add insignificant time (really, none)
to a single hash iteration.

Hashes like MD5, SHA1, and even SHA256 are _designed to be fast_. To succeed,
they need to be able to handle multi-gigabit per-packet hash rates. They are
designed explicitly both to be fast on general-purpose hardware and to be
straightforward to optimize in purpose-built hardware. This is a bad, bad
property for a password hash.

BCrypt is "optimized" to be slow - tuneably slow. SCrypt improves on BCrypt by
being both slow on general purpose hardware and resistant to simple hardware
speedups. PBKDF and "stretched" SHA1 are very simple contructions that are
weaker than BCrypt and SCrypt but more buzzword compliant. All of them make it
difficult to recover hundreds of thousands of passwords from a database dump.

See:

[http://www.matasano.com/log/958/enough-with-the-rainbow-
tabl...](http://www.matasano.com/log/958/enough-with-the-rainbow-tables-what-
you-need-to-know-about-secure-password-schemes/)

~~~
jmillikin
"salting" also prevents brute-forcing. Assuming a bare-basics implementation
(20-char salt in config file, 20-char salt per user, prepended to the
password), the only way an attacker can brute-force passwords in a reasonable
timeframe is to compromise the server itself. At that point, it would be just
as easy to make the login form mail him passwords.

Merely choosing a slower digest doessn't help, because the digest would have
to be extremely slow (minutes or hours per password) to prevent somebody from
running it against "password", "12345", etc for every row in the table. And
that's the only kind of attack worth preventing -- if somebody can brute-force
a 20-character alpha-num-symbol password in realtime, your choice of digest
algorithm is irrelevant.

~~~
tptacek
If you can't understand the significance of these two results (and this is
with the _default_ cost factor for BCrypt), you're just arguing to hear
yourself talk.

    
    
      t1 = Time.now.to_i
      100.times { BCrypt::Password.create("ugh8&eat") } 
      puts Time.now.to_i - t1
      => 12
    
      t1 = Time.now.to_i
      100.times { Digest::SHA1.hexdigest("ugh8&eat") } 
      puts Time.now.to_i - t1
      => 0
       

I could raise the number of iterations to bring SHA1 above the measurement
floor, but I don't want to lock my computer up with pointless BCrypt cycles.

~~~
jmillikin
Using these numbers, it would take your computer roughly 12 years to check 32M
passwords against that string. That's a long time, but feasible (with
additional power), and more specialized systems can bring it within reach.

In contrast, assuming a 40-character (20 in config, 20 in database)
alphanumeric salt, an attacker would have to perform
704423425546998022968330264616370176 digests _per row_ to check 32M passwords.

Unless you believe that is an insufficient barrier, implementing BCrypt is
merely degrading the user experience (12-second logins? come _on_ ) for no
real improvement.

~~~
harpastum
I think that the salient detail is this:

    
    
        t = Time.now.to_i
        1000000.times {Digest::SHA1.hexdigest("ugh8&eat")}
        puts (Time.now.to_i - t).to_s
        =>3
    

Sure, 120ms is a bit long, but I think it would be beneficial to security to
require more than 3µs.

Edit: I match my parent's problem with 32M checks taking 12 years with my
personal computer taking 132.86 seconds to calculate 32M SHA1s.

~~~
jmillikin
There are lots of ideas which are beneficial, but not particularly useful. For
example, requiring passwords to be at least 120 characters would (in theory)
make passwords more difficult to compromise, but in practice users are just
going to type "password" 15 times.

Increasing the digest time prevents an attacker with simultaneous access to
the server and database from cracking very weak passwords, but at the cost of
tripling or quadrupling how much time each request takes. There are some cases
where this could be useful -- for example, running a dissident website in an
authoritarian country -- but it's user-hostile to implement it anywhere else.

~~~
tptacek
Calculating a BCrypt hash with the default cost factor takes about as long as
reading an uncached file off a conventional filesystem. What a silly thing to
try to optimize. Really? It's killing you to spend 100ms on password hashing?
Ok, dial it down to 50ms. BCrypt is tunable.

------
mattmaroon
Wait a sec, something is wrong here. I suspect the title is misleading.
RockYou has maybe a couple thousand developers tops using their services. They
might have 32 million Facebook customers, but those don't have passwords.
They're Facebook app users.

Facebook does not permit developers to store private info without special
permissions, which I've never seen apps of their ilk ask for. So while this
hacker could maybe see what digital birthday card was sent to whom, that's
probably about the extent of the damage.

~~~
far33d
RockYou was a widget company - they probably still have usernames and
passwords for myspace users.

------
jasonlbaptiste
This is just some amateur hour shit. They're a well established and well
funded company. How do venture funds not do better technical due diligence(or
any at all)? I wouldn't release an app for 32 of my friends to test, let alone
32 million people to use with plain text passwords. Enough of my bitching,
because it's inaction. Now for words of action/openings for suggestion: How do
we make sure companies don't do dumb things like this?

~~~
tptacek
My answer to this question is effective but very self-serving.

~~~
ephermata
Train our runtimes to detect and reject attempts to store user passwords in
plaintext?

~~~
anigbrowl
I think the correct answer is 'hire tptacek' :)

~~~
tptacek
^ people like

------
mattmaroon
I'm not shocked. As I just wrote on my Posterous, RockYou has consistently
shown themselves to be just amazingly stupid. I've had the misfortune of
dealing with these morons for over a year now. This is far less bad (since I
use Roboform) than the time they CC'ed me in with thousands of people on a
Merry Christmas email.

------
gfunk911
What's the plumber equivalent of storing passwords in plaintext, the things
where if you heard that a plumber did X, you would be in complete shock at
their negligence?

~~~
ars
How about: Install a drain without a vent.

Why do you want to know?

Edit: I picked this example carefully. Someone who knowns nothing about
plumbing will not be shocked at this, having no idea what it is (until it's
explained to them). Just like someone who is not a programmer will have no
idea what the problem with plain text password is (until it's explained to
them).

PS. A drain without a vent (or at least an anti-siphoning device) can be life
threatening.

------
anigbrowl
given the nature of their service, I can't help suspecting the bulk of their
clientele use one password for everything. Awesome.

~~~
harpastum
I agree with you, in that you're saying it's silly for RockYou to assume their
customer's passwords are unique to their service, but I vehemently disagree
with your unstated assumption--that 99.99% of other communities aren't just as
likely to have users pick dumb passwords.

I don't mean this to come off as ad hominem, because I don't think it was your
intention to leave the opposite side of the argument open and I think you
personally understand the issue. I just think that we shouldn't have a
mentality of "aww, we need to take special care of these unsavvy users." Not
having basic levels of security in place for any user-base is simply
unacceptable.

~~~
anigbrowl
You're entirely right, and said it better than my snarky response did.

------
billclerico
if true, this is so irresponsible it is almost unbelievable

~~~
tptacek
Didn't Reddit do something very similar?

~~~
ichverstehe
Many do. E.g. 37signals.

~~~
tptacek
37signals lost a bunch of plaintext passwords? When did that happen?

~~~
qeorge
They didn't lose them, someone just noticed that they would send you your
original password if you requested it and made a blog post about it.

The conclusion was that they must be storing passwords plaintext, although
that's not necessarily true. IIRC, your opinion was that this was not a big
deal in the grand scheme of things.

~~~
tptacek
I said it wasn't a vulnerability, or, if it was, it was a minor one compared
to a real vulnerability; sev:low compared to sev:medium for a stored XSS flaw
and sev:high for SQL Injection. And I believe that.

But if we're comparing one password storage mechanism to another, I get
religious fast. There's a right and a wrong way to do it.

37s did it the wrong way. Now I understand they do it the right way. Good for
them!

~~~
qeorge
Yeah, I remember that better now. There were a lot of pitchforks that day.

37s has a great track record of listening to and acting on community feedback,
which is all you can really ask for. I second your kudos.

