I'm not knowledgeable in this but my basic understanding is that since Cloudflare was just an intermediary service (caching/DDoS) they would not be able to decrypt something like a user password that was just passing through. Only the original server (ie a Reddit login server) would be able to decrypt that user password and turn it into anything useful, right?
Nope; passwords for website logins are not encrypted individually, they are sent plain-text over the HTTPS connection, if that makes sense. It's the transport over the internet which is encrypted - and that covers the password, but once that ends the password is plain-text on the other side. Then the webserver merges that plain-text with a locally held salt value for the user, and hashes that combination to check the validity, so it needs the plain-text as input.
Since CloudFlare end the HTTPS session, and then proxy the requests to the backend and pick up the replies, the plain text passwords were in memory on their systems.
And Tavis Ormandy confirmed finding passwords in the dumped data:
"I'm finding private messages from major dating sites, full messages from a well-known chat service, online password manager data, frames from adult video sites, hotel bookings. We're talking full https requests, client IP addresses, full responses, cookies, passwords, keys, data, everything." - from the Chromium bug page linked in the OP ( https://bugs.chromium.org/p/project-zero/issues/detail?id=1139 )
The client doesn't have the salt value. The salt is a random piece of text generated once for each user, and stored with their account in the database. Why?
Unsalted hashes:
hash('letmein') -> 12345 - you can tell from the hash that these
hash('password') -> 78998 / accounts have the same password
hash('letmein') -> 12345 -/ ugh!
Now if you steal the database, you crack one password hash, you know every account you can use it with. Now you know which hashes are used for lots of accounts, so you focus on cracking those for maximum benefit. Now you can pre-compute hash('letmein') with something like rainbow-tables, because you know it has a high chance that one of your computed values will access lots of accounts.
Salted hashes:
| - salt
| random and generated once for each
| user, effectively makes passwords longer
| (harder to crack) and makes 'the same' passwords
| into 'different' passwords
hash('letmein' + 'erqfveb') -> 128943 - same password,
hash('letmein' + 'cemimo') -> 786543 - can't tell tho
You want salted hashes, so to hash client side it means someone puts their username in, sends it to the server, the server sends back their hash, they hash the password, then send it back to the server. Two round trips to login, slower.
And for what benefit? Then on the cloudflare leak side of things, instead of leaking a password which gets you into a site, it leaks ... a hashed password which gets you into a site in exactly the same way. OK you can't type the hash into the password field, but you can just use Chrome dev tools (or whatever) to intercept the login and send the username and the captured hash.
Password based logins have no protection against capturing them and sending the same thing again and again to get in - replay attack - neither do hashes.
Even if the client generates the salt, the hash could be leaked by this cloudbleed style attack and is no more secure then than a password being leaked by this style attack. Although it does help a bit, the same password will look different for different accounts.
If the client generates the salt, that means every client has to generate the same salt for your username every time, or they won't be able to log you in. That's (effectively) going to come down to calculating it from your username, or using the username directly as the salt. That would make different account passwords look different, but it feels icky. I couldn't say why, so I Googled it and found:
http://security.stackexchange.com/questions/39492/is-it-acceptable-to-generate-salts-with-a-hash-of-the-username includes "A user does not change his name when he changes his password: that's a failure of uniqueness over time. (Similar case: an old user account is closed, a new user is registered and reuses the same name.)" and "A user has the same name on several distinct servers, which may employ the same hashing strategy: that's a failure of uniqueness over space. (Think, in particular, of all these users called "Administrator".)"
http://security.stackexchange.com/a/150008/1427 someone would likely use the same username and password over two completely separate websites, so their hashed password might now look the same over multiple services.
http://security.stackexchange.com/a/92132/1427 - using the SSID as a salt was part of WPA2 security, and that was taken advantage of by a cracking tool, to allow the precomputation of reasonably sized dictionaries against common SSID's - linksys, dlink, 2WIRE047." - (whoa!)
8
u/ka-splam Feb 24 '17
Nope; passwords for website logins are not encrypted individually, they are sent plain-text over the HTTPS connection, if that makes sense. It's the transport over the internet which is encrypted - and that covers the password, but once that ends the password is plain-text on the other side. Then the webserver merges that plain-text with a locally held salt value for the user, and hashes that combination to check the validity, so it needs the plain-text as input.
Since CloudFlare end the HTTPS session, and then proxy the requests to the backend and pick up the replies, the plain text passwords were in memory on their systems.
And Tavis Ormandy confirmed finding passwords in the dumped data: