Can you trust 37signals with your password?(jgc.org)
jgc.org
Can you trust 37signals with your password?
http://www.jgc.org/blog/2009/05/can-you-trust-37signals-with-your.html
138 comments
Oh boy, that's an embarrassing newbie mistake to make.
What's worse is that they've known that it's an embarrassing security flaw for years, but they apparently thought other things were more important. Not really very comforting.
"Embarassing security flaw"? Come on. We audit several major web applications every week --- things that are far more sensitive than 37s, like banking, trading, and pension --- and we see sites store plaintext passwords all the time. I've never seen any vendor's security report write someone up for this. If it did get written up, it'd be "Severity: Low", along with "enabling weak SSL ciphers" and "exposed server version information".
I'm not trying to be an apologist here, but "someone is wrong on the Internet" if they are saying that storing passwords badly is a major vulnerability.
I'm not trying to be an apologist here, but "someone is wrong on the Internet" if they are saying that storing passwords badly is a major vulnerability.
I didn't expect to see a downplaying comment from you after your strong stances in this thread and your article:
http://news.ycombinator.com/item?id=576021
Is it a big deal to properly store the passwords or isn't it?
> stop working on your social shopping cart calendar application right now: I can’t trust you with my Reddit karma score, let alone my credit card number.
and that's what you said for developers using fast 1-way hashes. So it's embarrassing to use md5+salt, but not embarrassing to use plaintext?
The method we use for storing passwords is either vital or it's not-- I'm currently lost as to how you could respond like the above and have such strong feelings about the matter in other discussions.
http://news.ycombinator.com/item?id=576021
Is it a big deal to properly store the passwords or isn't it?
> stop working on your social shopping cart calendar application right now: I can’t trust you with my Reddit karma score, let alone my credit card number.
and that's what you said for developers using fast 1-way hashes. So it's embarrassing to use md5+salt, but not embarrassing to use plaintext?
The method we use for storing passwords is either vital or it's not-- I'm currently lost as to how you could respond like the above and have such strong feelings about the matter in other discussions.
Two thoughts I'm asking you to keep in your head simultaneously:
(1) It is very bad to store passwords in plaintext, with a naked SHA1 hash, or with a naked SHA1 hash and a salt of any kind.
(2) As bad as it is to do that, it is not a critical security vulnerability in your application to make that mistake.
The classic web pester example of a "Medium" severity vulnerability: reflected cross-site scripting ("here, follow this link --- hah, now I own your session!"). If you tell me that reflected cross-site scripting is less bad --- or even the same level of bad --- as storing passwords poorly, I'll accuse you of being disingenuous.
See downthread, upthread, and sidethread for examples of me pointing out my stance on safe password storage.
(1) It is very bad to store passwords in plaintext, with a naked SHA1 hash, or with a naked SHA1 hash and a salt of any kind.
(2) As bad as it is to do that, it is not a critical security vulnerability in your application to make that mistake.
The classic web pester example of a "Medium" severity vulnerability: reflected cross-site scripting ("here, follow this link --- hah, now I own your session!"). If you tell me that reflected cross-site scripting is less bad --- or even the same level of bad --- as storing passwords poorly, I'll accuse you of being disingenuous.
See downthread, upthread, and sidethread for examples of me pointing out my stance on safe password storage.
Sorry, man, I kind of can't take "disingenuous" accusations seriously as that was the word on the tip of my tongue when I read your surprising statement earlier in the thread. It doesn't sound like the same person I read before, nor from someone with your (deserved) status as a learned engineer on security matters.
The point you disagreed with was whether this was an embarrassing security flaw:
> "Embarassing security flaw"? Come on.
and that's what I'm calling you on based on our earlier discussions. I'm not making any point about how this compares to other security flaws, I'm just trying to figure out where you really stand on plaintext.
An earlier quote from you as I try to sort this out:
> People get to access password hashes as soon as you mess up a single database query. The idea behind storing safe hashes is to prevent your stupid mistakes from screwing over every one of your users. The stupidest people of all are the ones who assume they aren't going to make stupid mistakes.
So, the question at hand: Is it an embarrassing security flaw to use plaintext passwords for a modern, respected website?
The point you disagreed with was whether this was an embarrassing security flaw:
> "Embarassing security flaw"? Come on.
and that's what I'm calling you on based on our earlier discussions. I'm not making any point about how this compares to other security flaws, I'm just trying to figure out where you really stand on plaintext.
An earlier quote from you as I try to sort this out:
> People get to access password hashes as soon as you mess up a single database query. The idea behind storing safe hashes is to prevent your stupid mistakes from screwing over every one of your users. The stupidest people of all are the ones who assume they aren't going to make stupid mistakes.
So, the question at hand: Is it an embarrassing security flaw to use plaintext passwords for a modern, respected website?
It may be embarassing, and it may be a flaw, but if you sent it to Bugtraq or asked ZDI to pay you for it, you'd get laughed at. I'm not making that up, it's obviously true, so why are you arguing with me about it?
If you contract a team from Matasano to assess your website, and all we come back with is "you store passwords insecurely", we're the ones who will be embarassed. Sorry. Hate on 37s all you want, but in no parallel universe is "weak password storage" a gameover.
If you contract a team from Matasano to assess your website, and all we come back with is "you store passwords insecurely", we're the ones who will be embarassed. Sorry. Hate on 37s all you want, but in no parallel universe is "weak password storage" a gameover.
OK, so then to be sure I'm understanding, let me walk through how Django (in the default auth backend -- this is customizable if you want to plug in another scheme, as people often do) does it:
1. The "password" field in the DB holds a value of the form "algorithm_name$nonce$hash".
2. "algorithm_name", by default, is SHA1, but the backend lets you also use in MD5 (for backwards compatibility) or Unix crypt if you're running on a platform which has it.
3. "nonce" is the first five digits of the hex digest of a pair of floats pulled (at the time the password is set) from Python's 'random.random()' (which, of course, is a PRNG, not a truly random source of numbers).
4. "hash" is the result of applying the algorithm to the combination of the plain-text password and the nonce.
It's a bit confusingly set up internally because the code refers to the nonce as "salt" even though it's different (within the limits of Python's PRNG) for each stored password. And there's some fun legacy stuff in there that transparently switches naked MD5 hashes over to the algo/nonce/hash scheme when possible, which makes even more fun.
As best I can tell, this is the sort of scheme you're recommending, or at least that you're not outright bashing. Is that correct, or have I missed something?
We've had requests to open up the variety of hashing algorithms supported in the default backend, and AFAIK the jury's still kinda out on that one due to various compatibility issues with existing DBs and older Pythons, and the ease with which alternate authentication schemes can be plugged in.
1. The "password" field in the DB holds a value of the form "algorithm_name$nonce$hash".
2. "algorithm_name", by default, is SHA1, but the backend lets you also use in MD5 (for backwards compatibility) or Unix crypt if you're running on a platform which has it.
3. "nonce" is the first five digits of the hex digest of a pair of floats pulled (at the time the password is set) from Python's 'random.random()' (which, of course, is a PRNG, not a truly random source of numbers).
4. "hash" is the result of applying the algorithm to the combination of the plain-text password and the nonce.
It's a bit confusingly set up internally because the code refers to the nonce as "salt" even though it's different (within the limits of Python's PRNG) for each stored password. And there's some fun legacy stuff in there that transparently switches naked MD5 hashes over to the algo/nonce/hash scheme when possible, which makes even more fun.
As best I can tell, this is the sort of scheme you're recommending, or at least that you're not outright bashing. Is that correct, or have I missed something?
We've had requests to open up the variety of hashing algorithms supported in the default backend, and AFAIK the jury's still kinda out on that one due to various compatibility issues with existing DBs and older Pythons, and the ease with which alternate authentication schemes can be plugged in.
The Django scheme is what tptacek refers to as a "naked sha1 plus salt" and recommends against, because it is computably feasible to brute force it due to sha1 being a fast algorithm. His recommendation is to use a more computationally expensive hash such as bcrypt (based on blowfish) or possibly a few thousand iterations of sha1.
I guess this is where I'm getting confused. In some places I see comments which seem to say that "naked hash plus salt" is bad when the salt is the same every time, but possibly not when the salt is different every time. And, of course, in other places I see comments saying that this isn't any good either. And then stuff which has nothing to do with salts or nonces but solely looks at the algorithm (which I don't understand, because even the most up-to-date stuff on attacking popular hashes still seems to be orders of magnitude behind the efficiency of rainbow tables, and rainbow tables don't do as well against a salt that changes with every password).
And, well, this is where I just kinda go off the rails, because it seems as if there's nothing that's ever been conceived by man that doesn't have an article by a security expert saying "what are you, some kind of idiot? Why would anybody use that?"
And, well, this is where I just kinda go off the rails, because it seems as if there's nothing that's ever been conceived by man that doesn't have an article by a security expert saying "what are you, some kind of idiot? Why would anybody use that?"
I don't believe that this topic is, in practice, hard to understand.
You do face the challenge of sorting through all the noise of proposals and retorts --- "what if I use a 64 bit salt?", "what if I use SHA-256 instead of MD5", "what if I use AES to encrypt the passwords", "what if I run SHA1 in Javascript and just exchange the hashes", etc, etc, etc. None of this stuff matters.
The core issue is: your password hash should be cryptographically slow. It should resist account-at-a-time brute force attacks, which are the predominant method used to crack accounts. You can safely ignore the rest of the sideshows.
And finally, I have to say that just because a topic seems annoyingly complex doesn't mean it morally has to be simpler. If security experts are telling you you're an idiot for doing X, by all means get pissed that they called you an idiot, but also stop doing X.
You do face the challenge of sorting through all the noise of proposals and retorts --- "what if I use a 64 bit salt?", "what if I use SHA-256 instead of MD5", "what if I use AES to encrypt the passwords", "what if I run SHA1 in Javascript and just exchange the hashes", etc, etc, etc. None of this stuff matters.
The core issue is: your password hash should be cryptographically slow. It should resist account-at-a-time brute force attacks, which are the predominant method used to crack accounts. You can safely ignore the rest of the sideshows.
And finally, I have to say that just because a topic seems annoyingly complex doesn't mean it morally has to be simpler. If security experts are telling you you're an idiot for doing X, by all means get pissed that they called you an idiot, but also stop doing X.
"And finally, I have to say that just because a topic seems annoyingly complex doesn't mean it morally has to be simpler."
I'm OK with complexity. What I'm not OK with is the impression I get that there simply is no option that won't get shouted down. "Making the right choice is complex" is fine when compared to "there is no right choice".
I'm OK with complexity. What I'm not OK with is the impression I get that there simply is no option that won't get shouted down. "Making the right choice is complex" is fine when compared to "there is no right choice".
Nobody will shout you down for iterating SHA1 or for using one of the bcrypt/scrypt/PBKDF.
In actual fact, I won't even shout at you for using salted single-pass SHA1, as long as you don't brag about it, or talk about how your "salt" construction improves security.
In actual fact, I won't even shout at you for using salted single-pass SHA1, as long as you don't brag about it, or talk about how your "salt" construction improves security.
Well, in an ideal world I'd be in favor of using something better than what we currently have as the default, but for now we have to strike a compromise -- SHA1 is about the "best" hash that's ubiquitously available on the platforms and Python versions we support. Down the road when we've deprecated a couple older Python releases and can rely on things like hashlib being available, it'll be time to talk about improving the default setup.
And, in the context of common use cases, I think it's probably an OK compromise -- I doubt somebody's going to devote the resources to plucking the password for a random blog, for example. Once you need tougher security, you can plug in whatever scheme you like for storing credentials and authenticating users which, anecdotally, most people seem to be doing when warranted (there are quite a few third-party auth backends floating around). And, really, if I were going to brag about anything, it'd probably be the ease with which you can do that -- one class with two methods, a settings tweak and (depending on your credential scheme) possibly a short form class that knows what the incoming data will look like, and you're done. Of course, I think we could make it even easier, so I won't be bragging about it just yet :)
And, in the context of common use cases, I think it's probably an OK compromise -- I doubt somebody's going to devote the resources to plucking the password for a random blog, for example. Once you need tougher security, you can plug in whatever scheme you like for storing credentials and authenticating users which, anecdotally, most people seem to be doing when warranted (there are quite a few third-party auth backends floating around). And, really, if I were going to brag about anything, it'd probably be the ease with which you can do that -- one class with two methods, a settings tweak and (depending on your credential scheme) possibly a short form class that knows what the incoming data will look like, and you're done. Of course, I think we could make it even easier, so I won't be bragging about it just yet :)
Are SHA-512 and Whirlpool considered acceptable?
SHA-512 and Whirlpool are still designed to be very fast. The point is, you want to slow down the password hashing operation. So SHA-512, SHA-256, and SHA-1 are all fine, as long as you iterate them several thousand times.
I worked on a bank's web application and I recall our debating this very thing vigorously. We did have security audits, and if we did something like this we would expect the subject to come up in an audit.
The reason we wouldn't have considered this to be a "major" security vulnerability is that compromising our database would already be a major catastrophe, so losing a few million people's passwords would be the least of our worries.
So for a bank, it's like the old joke about not needing to run faster than a bear, just faster than your buddy.
However, my guess is that 37Signals is a little different. We use campfire, but we do not discuss certain thing son it specifically because it is hosted on a 3rd party server. If 37Signals' database was compromised, we would be distressed to have our private conversations exposed, but we would be mortified if one of our developers' passwords was compromised and that became an attack vector into more sensitive information.
So I am suggesting it comes down to relative vulnerability. For a bank, a compromised database is a catastrophe whether it contains plaintext passwords or not. For an online chat application, a compromised database is not a catastrophe, but compromising user passwords might tilt the balance from inconvenient to embarrassing.
JM2C!
The reason we wouldn't have considered this to be a "major" security vulnerability is that compromising our database would already be a major catastrophe, so losing a few million people's passwords would be the least of our worries.
So for a bank, it's like the old joke about not needing to run faster than a bear, just faster than your buddy.
However, my guess is that 37Signals is a little different. We use campfire, but we do not discuss certain thing son it specifically because it is hosted on a 3rd party server. If 37Signals' database was compromised, we would be distressed to have our private conversations exposed, but we would be mortified if one of our developers' passwords was compromised and that became an attack vector into more sensitive information.
So I am suggesting it comes down to relative vulnerability. For a bank, a compromised database is a catastrophe whether it contains plaintext passwords or not. For an online chat application, a compromised database is not a catastrophe, but compromising user passwords might tilt the balance from inconvenient to embarrassing.
JM2C!
The slight fallacy there is assuming that it takes a full database compromise to extract the data.
One of the things I have found is that often data (especially high-use data like passwords & usernames) is able to be snuck out through much more creative routes - storing in plaintext means extraction is much more worth the effort :) no waiting around to crack the data instant use.
One of the things I have found is that often data (especially high-use data like passwords & usernames) is able to be snuck out through much more creative routes - storing in plaintext means extraction is much more worth the effort :) no waiting around to crack the data instant use.
If I sneak the passwords out, can't I also sneak customer personal data like bank balances, SSNs, and so forth? Most banks maintain more than enough information on a customer to perform an identity theft and then some major fun begins such as misappropriating the title to real estate.
I don't disagree it can be done, just pointing out that if we assume a compromised employee and a vector for removing the passwords, encrypting/hashing the passwords is like locking the side door of the stable.
I don't disagree it can be done, just pointing out that if we assume a compromised employee and a vector for removing the passwords, encrypting/hashing the passwords is like locking the side door of the stable.
Yes fair point.
But hashing the other data isnt practical - so it's the security vs. access tradeoff. You can hash passwords without much inconvenience.
Also with individual pieces of those other examples of data you mention it is not possible to gain access to the rest. Whereas with a password it IS. Damage limitation.
Finally the password and username (or email) are "front of the line". They HAVE to be accessible to an unauthorised client simply so said client can be authorised. Whereas the other data should require authorisation to access.
But hashing the other data isnt practical - so it's the security vs. access tradeoff. You can hash passwords without much inconvenience.
Also with individual pieces of those other examples of data you mention it is not possible to gain access to the rest. Whereas with a password it IS. Damage limitation.
Finally the password and username (or email) are "front of the line". They HAVE to be accessible to an unauthorised client simply so said client can be authorised. Whereas the other data should require authorisation to access.
The fact that this is a common mistake doesn't make it any less serious. I don't do security audits, but if I did I would certainly point out this sort of mistake -- because even if it doesn't affect this site's security very much, it certainly has an impact on their customers' security thanks to the reuse of passwords.
I'm going to have a hard time arguing that it isn't a mistake given my track record on the site.
My only argument here is that, mistake or not --- it's definitely a mistake --- it's not a "serious security vulnerability", at least not as the industry understands them.
My only argument here is that, mistake or not --- it's definitely a mistake --- it's not a "serious security vulnerability", at least not as the industry understands them.
From a theoretical security perspective, it's a terrible idea to store passwords in plaintext, but again there's a difference between theory and practice as you've stated. If your auditing can reduce/eliminate unauthorized out-of-band database access, then in practice storing plaintext passwords isn't a huge problem.
However, there's another practical aspect to consider: the password security of users. A perfect example from a month ago is a Christian dating website called Singles.org. The 4chan crowd discovered that if you replaced your user ID on the "profile edit" page with another user ID, you could edit another person's profile. The page also helpfully displayed the registered e-mail address and password, in plaintext.
Now, this is terrible programming on multiple levels, so you might want to discount my anecdote, but the attack vector isn't my main point.
The 4chan crowd, ravenous beasts that they were, attempted to use the Singles.org password to log into the victim's e-mail account. And their Facebook account. And their PayPal account. You can imagine the chaos they caused.
The user base had terrible password security, so easily around 20% of the accounts had the same password across multiple websites. I don't think it's an uncommon statistic: sadly, even I as a security-conscious person have used the same password more than once.
Our efforts should be to secure an application against all attack vectors, but hashing passwords is a veritable last defense to prevent an attack from spreading on to other websites.
Regardless of how an application is exploited, it's a safe assumption that the users' poor password security could spread the attack further. I would thus claim that plaintext passwords be at least a "medium" security issue.
However, there's another practical aspect to consider: the password security of users. A perfect example from a month ago is a Christian dating website called Singles.org. The 4chan crowd discovered that if you replaced your user ID on the "profile edit" page with another user ID, you could edit another person's profile. The page also helpfully displayed the registered e-mail address and password, in plaintext.
Now, this is terrible programming on multiple levels, so you might want to discount my anecdote, but the attack vector isn't my main point.
The 4chan crowd, ravenous beasts that they were, attempted to use the Singles.org password to log into the victim's e-mail account. And their Facebook account. And their PayPal account. You can imagine the chaos they caused.
The user base had terrible password security, so easily around 20% of the accounts had the same password across multiple websites. I don't think it's an uncommon statistic: sadly, even I as a security-conscious person have used the same password more than once.
Our efforts should be to secure an application against all attack vectors, but hashing passwords is a veritable last defense to prevent an attack from spreading on to other websites.
Regardless of how an application is exploited, it's a safe assumption that the users' poor password security could spread the attack further. I would thus claim that plaintext passwords be at least a "medium" security issue.
Being able to get access to plaintext passwords is obviously a terrible security flaw. But would it be much less bad if an attacker got access to a lot of hashed passwords? A dictionary attack will get you many of the plaintexts in a reasonable timespan. Possibly users with dictionary words as passwords are also more likely to share them across sites; certainly the intersection is nonempty.
People with strong passwords might remain safe, but not necessarily. A bruteforce is much more worthwhile when you're trying to crack thousands of passwords at a time. If there's no salting and the hash algorithm is widely used, you may not even need to worry about getting exactly the original rather than something which happens to collide with it.
Obviously hashing is still better than no hashing, especially since there will be cases where only a few passwords are leaked. But if a database containing passwords is stolen, it may be reasonable to assume all those passwords are compromised, even if they were hashed.
People with strong passwords might remain safe, but not necessarily. A bruteforce is much more worthwhile when you're trying to crack thousands of passwords at a time. If there's no salting and the hash algorithm is widely used, you may not even need to worry about getting exactly the original rather than something which happens to collide with it.
Obviously hashing is still better than no hashing, especially since there will be cases where only a few passwords are leaked. But if a database containing passwords is stolen, it may be reasonable to assume all those passwords are compromised, even if they were hashed.
If the password hashing scheme is secure (bcrypt, as tptacek repeatedly recommends) dictionary attacks become non-trivial and slow. It's still possible to brute force the database, of course, but the time required makes the attack less profitable.
I would thus argue that a secure hashing schema is significantly better. This is assuming the programmer uses bcrypt in the first place, which is a questionable assumption: even popular projects like phpBB use MD5 for password hashing. (The fools.)
If MD5 is used then I would wholeheartedly agree with you: I've used http://milw0rm.com 's MD5 hash breaking service plenty of times to know why I shouldn't use that algorithm in my own code. (One of my old passwords is in the database, but I'm not telling you which one.)
I would thus argue that a secure hashing schema is significantly better. This is assuming the programmer uses bcrypt in the first place, which is a questionable assumption: even popular projects like phpBB use MD5 for password hashing. (The fools.)
If MD5 is used then I would wholeheartedly agree with you: I've used http://milw0rm.com 's MD5 hash breaking service plenty of times to know why I shouldn't use that algorithm in my own code. (One of my old passwords is in the database, but I'm not telling you which one.)
To me it's a "serious security vulnerability" only in the sense that if they were that lackadaisical with their password storage, where else have they made poor decisions with regards to security?
I think you'll agree that security is not a single thing you do, but a series of things that makes getting at sensitive data more difficult. To store all passwords as plaintext (including passwords for administrators, I would assume) surely must be considered a serious oversight at the least.
I feel as though maybe we're missing some nuance in your position on this.
I think you'll agree that security is not a single thing you do, but a series of things that makes getting at sensitive data more difficult. To store all passwords as plaintext (including passwords for administrators, I would assume) surely must be considered a serious oversight at the least.
I feel as though maybe we're missing some nuance in your position on this.
I didn't say it was a major vulnerability; I said it was embarrassing. Given 37signal's stature in the web community, the ease with which this problem can be fixed, the fact that they said they would fix it years ago and haven't, and the fact that this is a basic problem with a well-known solution, I think this is embarrassing for them.
Really? We're going to downmod the most active security professional on HN? A guy who's built a 25+ person company on the basis of analyzing web applications for security? FFS, did we learn nothing from yesterday's expert kerfuffle?
If Thomas says it's not really a big deal in practice, then it's not really a big deal in practice.
If Thomas says it's not really a big deal in practice, then it's not really a big deal in practice.
Note that I might not be "the most active security professional on HN", but am certainly "the security professional most active on HN". There's a big difference. ;)
Note: I don't know who this "kubrick" person is, because he won't tell us, but "CISO of a financial institution or not", he's wrong about the OWASP Top 10.
Neither "broken authentication" nor "poor encryption" "top vulnerabilities" discuss password encryption. "Storing plaintext passwords" is not an OWASP Top 10 flaw.
"A7 Broken Authentication and Session Management" is a proxy for session fixation, and the catch-all category for things like "cookies that store the bit that tells the app whether you're the admin. It mentions passwords repeatedly without ever recommending they be encrypted; in fact, by talking about "Question and Answer" features, it tacitly acknowledges the practice.
"A8 Insecure Cryptographic Storage" means "don't invent your own crypto", and now also "don't use MD5". It mentions passwords zero times; the only thing it says need to be encrypted are credit cards. This makes sense, because if it said anything else, no real-world web app would pass muster.
Having said all that, I wouldn't put much stock in the OWASP Top 10 either. It's the most popular list of web flaws, but it isn't the most complete, nor is it the most coherent. It's not like there's science behind it.
Note: I don't know who this "kubrick" person is, because he won't tell us, but "CISO of a financial institution or not", he's wrong about the OWASP Top 10.
Neither "broken authentication" nor "poor encryption" "top vulnerabilities" discuss password encryption. "Storing plaintext passwords" is not an OWASP Top 10 flaw.
"A7 Broken Authentication and Session Management" is a proxy for session fixation, and the catch-all category for things like "cookies that store the bit that tells the app whether you're the admin. It mentions passwords repeatedly without ever recommending they be encrypted; in fact, by talking about "Question and Answer" features, it tacitly acknowledges the practice.
"A8 Insecure Cryptographic Storage" means "don't invent your own crypto", and now also "don't use MD5". It mentions passwords zero times; the only thing it says need to be encrypted are credit cards. This makes sense, because if it said anything else, no real-world web app would pass muster.
Having said all that, I wouldn't put much stock in the OWASP Top 10 either. It's the most popular list of web flaws, but it isn't the most complete, nor is it the most coherent. It's not like there's science behind it.
On the contrary, it's a big deal to me because it's my password and I judge that it's being stored in an insecure manner. I really appreciate Thomas's expertise, but since my data is at risk as a customer, my opinion is really the one that counts.
If you're not already using different passwords for each website, you can't really complain too much.
Do you believe there is any good reason for a site to store passwords in plaintext?
No.
I'm actually bizarrely fixated on this topic; go to "searchyc.com" and search for "bcrypt" and follow the threads. It is, apparently, all I ever talk about.
I'm not defending the feature. I'm just saying:
* Lots of companies have this feature.
* Among them are FedEx and several banks.
* If you wrote a security report for Basecamp and included this problem at all, it would be "Severity: Low". I'd write it up. But I wouldn't say "Severity: Critical", because I would get my ass kicked by my clients and partners.
The rest of this debate, have at it. I agree. BURN THE WITCHES.
I'm actually bizarrely fixated on this topic; go to "searchyc.com" and search for "bcrypt" and follow the threads. It is, apparently, all I ever talk about.
I'm not defending the feature. I'm just saying:
* Lots of companies have this feature.
* Among them are FedEx and several banks.
* If you wrote a security report for Basecamp and included this problem at all, it would be "Severity: Low". I'd write it up. But I wouldn't say "Severity: Critical", because I would get my ass kicked by my clients and partners.
The rest of this debate, have at it. I agree. BURN THE WITCHES.
Well also as a security professional (also called Thomas as it happens :P small world) I would point it out as at least a medium security flaw.
> because I would get my ass kicked by my clients and partners.
So your reasoning is nothing to do with security - it is to do with saying what the customer wants to hear (low severity stuff can be ignored, right?).
I have found the opposite in the past: encrypting passwords is, I agree, a common issue and one that is also usually very simple to fix. You can present that whole fix to the client and it can probably be implemented in a few weeks/months - it's useful because it is not something that will send them screaming to the hills but it is something so they feel they are getting value for money :) (plus you will likely get follow up work - if not to fix the problem then to audit the fixes!). Win win.
At the end of the day storing in plain text means it only takes on slip to release all your users passwords into the wild. It IS a big security flaw. If I walk away from an audit w/o flagging the password encryption as something to be addressed fairly soon and then the passwords are stolen my ass is properly on the line (probably more than any other issue).
And for the record I am talking as big if not bigger institutions than Fedex and US banks.
> because I would get my ass kicked by my clients and partners.
So your reasoning is nothing to do with security - it is to do with saying what the customer wants to hear (low severity stuff can be ignored, right?).
I have found the opposite in the past: encrypting passwords is, I agree, a common issue and one that is also usually very simple to fix. You can present that whole fix to the client and it can probably be implemented in a few weeks/months - it's useful because it is not something that will send them screaming to the hills but it is something so they feel they are getting value for money :) (plus you will likely get follow up work - if not to fix the problem then to audit the fixes!). Win win.
At the end of the day storing in plain text means it only takes on slip to release all your users passwords into the wild. It IS a big security flaw. If I walk away from an audit w/o flagging the password encryption as something to be addressed fairly soon and then the passwords are stolen my ass is properly on the line (probably more than any other issue).
And for the record I am talking as big if not bigger institutions than Fedex and US banks.
My reasoning is that usually we call out things that can actually allow an attacker to compromise the site, and don't spend as much time on the million things that might make an attacker's life easier after that compromise has occurred.
The rest of your argument is a moot point, because I'm not asserting that passwords should be stored plaintext.
The rest of your argument is a moot point, because I'm not asserting that passwords should be stored plaintext.
It's not really moot because I never assumed you were asserting that.
But you did just say that you would either not mention or flag as low priority (and the suggestion is grudgingly) a plain text passwords issue because "I would get my ass kicked by my clients and partners". I'll be honest - I wouldn't hire you if I had seen that written publicly like that :(
I sometimes think that one of the major failings in our industry is that we toe the corporate line and never stop to think like a cracker. That's why I have my job - because I do. Some people see plain text passwords as a "making life easier" issue, whereas for me it is a major weakness at the core of the security chain. Throw all you like in the way but, at the end of that day, the passwords are there in clear text waiting for me to find it. It doesn't matter how many different ways I can or cant compromise a site: all I need to do is do it once...
And anyway, my point was less about this specific issue than about how I think you address it wrong. The hashed passwords issue is one you can dress up for a client so they think they get value for money. If they get nothing except a green tick on the "critical errors" page then you leave them with the feeling that they are missing something. Hashing passwords should be fixed - and we can get them to fix it. And at the same time they get something meaningful from their audit :)
But you did just say that you would either not mention or flag as low priority (and the suggestion is grudgingly) a plain text passwords issue because "I would get my ass kicked by my clients and partners". I'll be honest - I wouldn't hire you if I had seen that written publicly like that :(
I sometimes think that one of the major failings in our industry is that we toe the corporate line and never stop to think like a cracker. That's why I have my job - because I do. Some people see plain text passwords as a "making life easier" issue, whereas for me it is a major weakness at the core of the security chain. Throw all you like in the way but, at the end of that day, the passwords are there in clear text waiting for me to find it. It doesn't matter how many different ways I can or cant compromise a site: all I need to do is do it once...
And anyway, my point was less about this specific issue than about how I think you address it wrong. The hashed passwords issue is one you can dress up for a client so they think they get value for money. If they get nothing except a green tick on the "critical errors" page then you leave them with the feeling that they are missing something. Hashing passwords should be fixed - and we can get them to fix it. And at the same time they get something meaningful from their audit :)
* It's the easiest to code
* The probability of your servers getting hacked/stolen is reasonably low as long as you take other precautions.
For most people, I'd say it's a lot of extra work, for no real pay-off - apart from making your users feel a bit more warm and fuzzy.
A better solution would probably just be a disclaimer on websites saying "Please don't use the same password you use for online banking here, as that would be silly".
* The probability of your servers getting hacked/stolen is reasonably low as long as you take other precautions.
For most people, I'd say it's a lot of extra work, for no real pay-off - apart from making your users feel a bit more warm and fuzzy.
A better solution would probably just be a disclaimer on websites saying "Please don't use the same password you use for online banking here, as that would be silly".
Embarrassing as in known to everybody who builds web apps for a living and very easy to fix, and yet this way.
If it was really a big security flaw, it would have been exploited in those 'several years'.
Granted, it doesn't make you feel warm and fuzzy, but there's a lot worse.
Granted, it doesn't make you feel warm and fuzzy, but there's a lot worse.
Famous last words: "If it was really big, it would have been exploited already."
Never mind industry best practices or the cautionary incidents at other companies -- this "it's not big until it bites us" attitude can be used to deprioritize fixing any risky behavior until it's too late.
There are low-stakes situations where this attitude is a virtue -- where the damage from an exploit is minor and quickly reversible. For famous and business-class internet services, the stakes are high.
Never mind industry best practices or the cautionary incidents at other companies -- this "it's not big until it bites us" attitude can be used to deprioritize fixing any risky behavior until it's too late.
There are low-stakes situations where this attitude is a virtue -- where the damage from an exploit is minor and quickly reversible. For famous and business-class internet services, the stakes are high.
Just like Microsoft. :)
In the same sense that my Japanese builder not using deadbolts and reinforced bars on the first floor windows, it is certainly a newbie mistake. Granted, there hasn't been a breakin in this ward in 5 years, but it could happen and then he'd be sorry he saved the $200 on his last 100 apartments.
There are costs to absolutely everything, even doing the hashed password in the DB trick.
Specifically, it puts one more bar in front of people logging into their account, particularly for some users who are habitually incapable of remembering their passwords and use the remember password link every single freaking time. (These people exist. Everyone collects stats, right?) You all know the conversion rate dieoff that happens as you add each additional form element to a checkout or survey form, right? And how increasing any funnel by a webpage increases the failure rate of the funnel, right? Well, imagine the equivalent of both adding an extra form element and an extra web access, right in the middle of the funnel, and if the user fails to get through the funnel they don't just bounce, they stop using your service for good.
At 37Signals scales, losing half of the 10% or so of accounts which might need password recovery is worth a lot of money. At least several tens of thousands a year. That is an awfully big price to pay as the insurance premium against someone getting a full compromise of their database. (Though I'm sure their users would be grateful if the insurance worked. "Well, sucks that an unknown hacker has a tarball of all the business contacts I've ever put in your database. On the other hand, at least you didn't compromise my password -- my gmail remains safe!")
There are costs to absolutely everything, even doing the hashed password in the DB trick.
Specifically, it puts one more bar in front of people logging into their account, particularly for some users who are habitually incapable of remembering their passwords and use the remember password link every single freaking time. (These people exist. Everyone collects stats, right?) You all know the conversion rate dieoff that happens as you add each additional form element to a checkout or survey form, right? And how increasing any funnel by a webpage increases the failure rate of the funnel, right? Well, imagine the equivalent of both adding an extra form element and an extra web access, right in the middle of the funnel, and if the user fails to get through the funnel they don't just bounce, they stop using your service for good.
At 37Signals scales, losing half of the 10% or so of accounts which might need password recovery is worth a lot of money. At least several tens of thousands a year. That is an awfully big price to pay as the insurance premium against someone getting a full compromise of their database. (Though I'm sure their users would be grateful if the insurance worked. "Well, sucks that an unknown hacker has a tarball of all the business contacts I've ever put in your database. On the other hand, at least you didn't compromise my password -- my gmail remains safe!")
I don't buy that argument. When someone clicks "I forgot my password", you e-mail them a one-time link to log in to their account. They click it, and they're in. That's easier than checking your e-mail and then typing a password.
Not to mention that 37signals accounts are paid for - so there's a much higher incentive for people who forget their password to go through the flow to recover that account - otherwise they'll be wasting their money!
Not to mention that 37signals accounts are paid for - so there's a much higher incentive for people who forget their password to go through the flow to recover that account - otherwise they'll be wasting their money!
All you've done then is replaced the login process with the "forgot password" link. Every time this user logs in, you'll send him another random password, which he'll forget again immediately.
Worse, systems like yours usually ask for a new password when you log in again, but complain when the user supplies "password" or "letmein" because it doesn't have enough @ signs. And then it complains again when the user picks a password he's used before.
Maybe that's fine if you're a bank (though all it does is shift the plain-text password storage from your database to a sticky note on the front of your user's monitor), but if your site is just another URL shortener or whatever, I simply don't care how you store my password provided you can give it back to me intact when I ask for it.
Worse, systems like yours usually ask for a new password when you log in again, but complain when the user supplies "password" or "letmein" because it doesn't have enough @ signs. And then it complains again when the user picks a password he's used before.
Maybe that's fine if you're a bank (though all it does is shift the plain-text password storage from your database to a sticky note on the front of your user's monitor), but if your site is just another URL shortener or whatever, I simply don't care how you store my password provided you can give it back to me intact when I ask for it.
Don't send them a random password. Send them a one-time login link (which is kind of like a random password, but it's embedded in the URL so you don't need to type it in to anything). The first screen they see once they're in asks them to reset their password.
For my own projects I don't set any limits on passwords that people enter - if they want to use an insecure password that's their problem.
For my own projects I don't set any limits on passwords that people enter - if they want to use an insecure password that's their problem.
I agree. That's the way forward.
A password that they can remember beats a password written on their monitor, even if it's not that strong.
A password that they can remember beats a password written on their monitor, even if it's not that strong.
how hard is it to program a "password strength" detector into these apps?
If you routinely forget your password it doesn't really matter if you always get a new/different password, now does it?
edit: not that this is the best way to go (see other comments) but it's still miles better than what they have now, with minimal intrusion for their users.
edit: not that this is the best way to go (see other comments) but it's still miles better than what they have now, with minimal intrusion for their users.
What's the problem with a "reset password" option?
I doubt that this is a mistake in the sense of an unintentional oversight, but a deliberate design decision, albeit a poor one. They might have taken the KISS principle too far this time, at the expense of security.
Instead of trusting every single provider of a service you use to safekeep your password, why not just use unique passwords for each service? I mean, really, you can't put the blame on each of the service providers if you choose to use the same password everywhere. That, if anything, is an embarrassing newbie mistake.
I have a repeatable method of coming up with a unique password for each service. I don't have to remember each unique password, only my method for producing a password.
Because my method is arbitrary rather than mathematic, I don't think anyone can figure it out even if given sample of passwords (I've challenged several who claim to be able to do so "easily"). And while my method is arbitrary, it's comprised of a few rules I know very well, which leads me to actually remember each unique password fairly well.
Don't outsource the job of safekeeping your password to every single vendor out there. Do it yourself.
I have a repeatable method of coming up with a unique password for each service. I don't have to remember each unique password, only my method for producing a password.
Because my method is arbitrary rather than mathematic, I don't think anyone can figure it out even if given sample of passwords (I've challenged several who claim to be able to do so "easily"). And while my method is arbitrary, it's comprised of a few rules I know very well, which leads me to actually remember each unique password fairly well.
Don't outsource the job of safekeeping your password to every single vendor out there. Do it yourself.
You mean like FedEx and several banks?
I don't love this design decision --- ok, no, wait, I hate this design decision --- but don't make it out to be something it isn't. The 37s team knows how to do "secure" password storage (that's every other Rails plugin ever written). They chose this because they thought it would make their customers lives easier.
I don't love this design decision --- ok, no, wait, I hate this design decision --- but don't make it out to be something it isn't. The 37s team knows how to do "secure" password storage (that's every other Rails plugin ever written). They chose this because they thought it would make their customers lives easier.
Do you have any evidence of this? They said two years ago that they were going to change it...what makes you think it's not just a case of them being lazy?
It is true that 37signals emphasizes making the lives of their customers easier. To a fault.
But I don't see how the password recovery feature would be any less easy and convenient if it consisted of sending an email with a password reset link that brings you to a page where you just enter a new password twice and get logged in immediately. You have to deal with password reset link expiry and such but no big deal.
But I don't see how the password recovery feature would be any less easy and convenient if it consisted of sending an email with a password reset link that brings you to a page where you just enter a new password twice and get logged in immediately. You have to deal with password reset link expiry and such but no big deal.
A lot of people don't like changing passwords.
You don't have to change it. Type in the same password if you really want.
Of course, if you knew what the password was in the first place, you wouldn't have needed to reset your password...
Of course, if you knew what the password was in the first place, you wouldn't have needed to reset your password...
I can come at this from the other end: part of my consulting deals with end-users on a daily basis, and I've seen even novice users _finally_ starting to use multiple passwords on their own without prompting.
So, it more likely would be a simple case of their forgetting which password they used on that particular system.
So, it more likely would be a simple case of their forgetting which password they used on that particular system.
[deleted]
I would take it a step further. Why email plain text passwords? It usually stays in your inbox. This increase the chance of someone being able to get your password. It now exists on your laptop/desktop and on a email server, depending on your settings. There should be a reset password, but not a recover password. Send a link to a secure page which asks for something the user knows/has username ?
99% of the time, if you own the mail spool behind an account on a web application, you own the account, because of password reset.
Yes, but with password reset you don't also own every other account the user has where they reused the same password.
You kind of do, since you can reset pretty much every password using email.
I think the point kind of is:
If the plain text password (which is reused on multiple sites) is sent out via email, then you need to compromise a single email in order to compromise many accounts.
If you want to abuse pasword-resetting mechanisms from N sites, you have to compromise N emails.
This means: mailing the password in plaintext might result in a lucky attacker seeing the password over your shoulder and then, he has access to a lot of stuff. If he just sees a password reset link, he has seen nothing. Of course, this includes compromising the account, because once the account is compromised, an arbitrary amount of emails is compromised (and thus, of course, also 1 email and N emails).
If you want to abuse pasword-resetting mechanisms from N sites, you have to compromise N emails.
This means: mailing the password in plaintext might result in a lucky attacker seeing the password over your shoulder and then, he has access to a lot of stuff. If he just sees a password reset link, he has seen nothing. Of course, this includes compromising the account, because once the account is compromised, an arbitrary amount of emails is compromised (and thus, of course, also 1 email and N emails).
Only the ones which have password reset mechanisms. My bank doesn't, for example, because they realize that intercepting someone's email shouldn't allow an attacker to get access to the victim's bank accounts -- but that wouldn't help me if I used the same password for my bank as I did for 37signals.
And? That has nothing to do with my point. I'm saying "the step forward" proposed upthread isn't one.
Apple dev site does this.
This kind of beginner mistake makes you wonder how 'hacker safe' their system really is. You can bet that they will be improving their security soon -- making bold claims about security is one way to guarantee lots of free pen testing.
> wonder how 'hacker safe' their system really is
It's not. Not more than anyone else, anyway. 37signals and Fog Creek are masters of marketing and mind control. There are free tools, or at least superior commercial tools, that do everything their stuff does.
It's not. Not more than anyone else, anyway. 37signals and Fog Creek are masters of marketing and mind control. There are free tools, or at least superior commercial tools, that do everything their stuff does.
Care to expand on that? I am looking for something for team collaberation like basecamp and curious as to what is out there.
I recommended basecamp to my boss to check out but after seeing this I am a little hesitant about it.
Edit: I am hesitant because I cannot guarantee that all the users of basecamp will use a different password than the normal one for their email.
I recommended basecamp to my boss to check out but after seeing this I am a little hesitant about it.
Edit: I am hesitant because I cannot guarantee that all the users of basecamp will use a different password than the normal one for their email.
you can try Tonido workspace
One thing worth pointing out is he's saying that they're storing plain text in the database, which may not be the case. They may be storing the password in the database with two way encryption. I'm not arguing the merits of that, only pointing out he's claiming fact on something he has no specific details on.
If the server can decode it so can anyone who has access to the server. Not only that, but 37S reveals the password of other people's accounts to the admin. Pathetic.
[deleted]
"If the server can decode it so can anyone who has access to the server."
Semantics.
Any type of security made by humans is breakable by humans.
Your reasoning is flawed.
Semantics.
Any type of security made by humans is breakable by humans.
Your reasoning is flawed.
[deleted]
Correct, the blog post is assuming the password is stored in plain text, when he doesn't even have hard evidence about it.
Two way encryption would be an explanation to this, so I am waiting on what 37s' answer to this blog post.
It's sad people quickly come to conclusions when only hearing one side of the story.
Two way encryption would be an explanation to this, so I am waiting on what 37s' answer to this blog post.
It's sad people quickly come to conclusions when only hearing one side of the story.
From a security standpoint, there is no difference between storing the password in plain text, and storing it encrypted with the keys on the server to decrypt it. It's like saying that having an unlocked safe is not the same thing as having a locked safe with the keys left in the lock. Why should the OP make the distinction?
Because there is a difference. Sure, academically, and positing an ability to break into anything, encrypting the passwords and retaining the key is useless. But realistically, I can think of a few ways off the top of my head where the difference might matter.
For example, you could have a dedicated decryption server holding the server-side key, carefully isolated from the rest of the internal network, its only channel of communication a single socket with request/response on decrypting passwords for password recovery. It could have rate limiting built in, and a storm of alerts to go off if backends request too many decryptions.
For example, you could have a dedicated decryption server holding the server-side key, carefully isolated from the rest of the internal network, its only channel of communication a single socket with request/response on decrypting passwords for password recovery. It could have rate limiting built in, and a storm of alerts to go off if backends request too many decryptions.
You're assuming the keys are the only way to get into the safe. There you go again with flawed reasoning.
What if I drill into the safe and open it in a different manner?
ANY type of security has it's weaknesses. The only way is to add layers of security to make it harder to crack.
What if I drill into the safe and open it in a different manner?
ANY type of security has it's weaknesses. The only way is to add layers of security to make it harder to crack.
Sure, I think everyone on HN agrees that any type of security has its weakness. What we are discussing here is whether 37signals is inadequately handling users' data by storing passwords in plain text, and the argument is that there is no difference in the level of security of "encrypted" passwords if the server has the key to decrypt them.
In other words, even if the author found out before writing the article that 37signals was storing users' passwords encrypted (instead of hashed), then he still would have written his article, and we would still be just as concerned as we are now.
You seem to be arguing against a point that no one is making.
In other words, even if the author found out before writing the article that 37signals was storing users' passwords encrypted (instead of hashed), then he still would have written his article, and we would still be just as concerned as we are now.
You seem to be arguing against a point that no one is making.
layered security is not the answer - if the weakness is elsewhere in your application then potentially passwords can be extracted in other ways (people run straight to SQL injection as the main source but any decent cracker will be able to explore other options).
Hashing and salting a password removes absolutely ewvery security weakness in terms of directly extracting the password. No need for layered security and potentially complex uneeded encryption/decryption in your app. Safe, secure. end of the matter :)
Hashing and salting a password removes absolutely ewvery security weakness in terms of directly extracting the password. No need for layered security and potentially complex uneeded encryption/decryption in your app. Safe, secure. end of the matter :)
"Hashing and salting a password removes absolutely ewvery security weakness in terms of directly extracting the password. No need for layered security and potentially complex uneeded encryption/decryption in your app. Safe, secure. end of the matter :)"
It is seriously worrying that you believe this.
Cracking hashed passwords offline is no big deal on a single machine unless you have really strong password policy - you know, the type of password no real regular user would even enter.
It is seriously worrying that you believe this.
Cracking hashed passwords offline is no big deal on a single machine unless you have really strong password policy - you know, the type of password no real regular user would even enter.
you think? I'll give you a 4 character password correctly salted and hashed with Sha1 and would like to see you crack it ;)
Allowing password security to depend on what the user enters IS silly - but who would! 32haracter salts and sha256 is going to produce a fairly uncrackable password.
Even if you know the salt and the salting algorithm (because simply appending a salt is also silly) it can still take a while :)
Im not talking about just sticking "MYSECRETSTRING" on the end of every password and sha1-ing it :)
Allowing password security to depend on what the user enters IS silly - but who would! 32haracter salts and sha256 is going to produce a fairly uncrackable password.
Even if you know the salt and the salting algorithm (because simply appending a salt is also silly) it can still take a while :)
Im not talking about just sticking "MYSECRETSTRING" on the end of every password and sha1-ing it :)
Ok to prove what I am talking about (because it is only fair I do). Here are four 4 character password correctly hashed and salted.
6fe4bc5a51a3967a3a5e8d2f2baadd08db8cfa87934d88c142b7f89a
2faf5762d544eafaea9792e90660bfd224ffda2bb5f4dd4435a011ba
86096426b8cef5ebbf438a3f743b955100a4a0b4f72593af7485a1bb
0522e582fb1186fb79934998be7ee04f6c4a607009218fa3c35cffc6
The hash algorithm used is sha1. The salting scheme uses a randomly generated salt and a known salting roation. I gave you 4 to give you fair chance to work on them. I'll give you more if you want. (there is no way to brute force these BTW so dont really bother :))
6fe4bc5a51a3967a3a5e8d2f2baadd08db8cfa87934d88c142b7f89a
2faf5762d544eafaea9792e90660bfd224ffda2bb5f4dd4435a011ba
86096426b8cef5ebbf438a3f743b955100a4a0b4f72593af7485a1bb
0522e582fb1186fb79934998be7ee04f6c4a607009218fa3c35cffc6
The hash algorithm used is sha1. The salting scheme uses a randomly generated salt and a known salting roation. I gave you 4 to give you fair chance to work on them. I'll give you more if you want. (there is no way to brute force these BTW so dont really bother :))
So basically the algorithm is in the code, so anyone who has ever seen the code knows the algorithm, which you can't change after you have actual users. Any ex-employee could take a copy of the verify function and a dump of the database and hack it home. Similarly a cracker who gets a DB dump of the passwords will probably get your code too.
Running sha1() in PHP on each of the 98569 words in /usr/share/dict/words takes 1 second on my laptop. Appending all of the numbers 1-100 to each of those, not surprisingly ups the time to about 1m40s. You'll probably get quite a lot of users with passwords like that.
Running sha1() in PHP on each of the 98569 words in /usr/share/dict/words takes 1 second on my laptop. Appending all of the numbers 1-100 to each of those, not surprisingly ups the time to about 1m40s. You'll probably get quite a lot of users with passwords like that.
Yes but that's NOT the issue were discussing here is it. You take steps to hide the algorithm from as many people as possible etc. It's not that hard to do.
Finally in a RL scenario I would use the password itself to generate the rotation schema. Provided you required at least 6 characters from your users and a least one number then you can quite fairly combat the brute force approach. The way to do this is to generate a completely random salt and then use the password to create a scheme to rotate the salt into the password. Then hash the result and use the known pattern & the password to generate another scheme to rotate the salt into the hash.
The advantage of this is that even if you have a the hash you cant just pull the hash out of the string and append the salt onto every password in your list & then hash it. You have to reverse engineer the salted hash for EVERY password substantially adding to your decryption time. Because the salt is also pseudo-randomly generated it also means that you have to attack every password in this way - you cant pre-generate all the possible hashes and test them because I have basically ignored what the user has entered and increased the keyspace up to around 8e+24. Even the brute force mechanism has a hurdle to overcome because the keyspace assuming an 8 char password is 2821109907456. (there are yet other steps to take to overcome the dictionary style attack)
Add in the requirement for the user to enter at least 8 characters at least one of which is a number and your making it a VERY bad day for a would be cracker :)
Finally in a RL scenario I would use the password itself to generate the rotation schema. Provided you required at least 6 characters from your users and a least one number then you can quite fairly combat the brute force approach. The way to do this is to generate a completely random salt and then use the password to create a scheme to rotate the salt into the password. Then hash the result and use the known pattern & the password to generate another scheme to rotate the salt into the hash.
The advantage of this is that even if you have a the hash you cant just pull the hash out of the string and append the salt onto every password in your list & then hash it. You have to reverse engineer the salted hash for EVERY password substantially adding to your decryption time. Because the salt is also pseudo-randomly generated it also means that you have to attack every password in this way - you cant pre-generate all the possible hashes and test them because I have basically ignored what the user has entered and increased the keyspace up to around 8e+24. Even the brute force mechanism has a hurdle to overcome because the keyspace assuming an 8 char password is 2821109907456. (there are yet other steps to take to overcome the dictionary style attack)
Add in the requirement for the user to enter at least 8 characters at least one of which is a number and your making it a VERY bad day for a would be cracker :)
Yes, this was my original point:
"Cracking hashed passwords offline is no big deal on a single machine unless you have really strong password policy"
i.e. if you allow users to set something weak as a password like a dictionary word then it doesn't matter what salting method you have, since you can try them all pretty quickly. (Probably saying "really" was pushing it a bit)
I've seen salting on it's own doesn't work since 'John the Ripper' (http://www.openwall.com/john/) can go though a password file that has a different salt for each user and find some passwords in a few seconds. It doesn't have rainbow tables, it just tries a given password with all of the different salts and compares them. This is why you also need a strong password.
You said: "Allowing password security to depend on what the user enters IS silly"
and now you are saying: "Provided you required at least 6 characters from your users and a least one number then you can quite fairly combat the brute force approach."
Now you are saying a salting combined with a strong password policy is the solution and not either in isolation. Which I agree with.
i.e. if you allow users to set something weak as a password like a dictionary word then it doesn't matter what salting method you have, since you can try them all pretty quickly. (Probably saying "really" was pushing it a bit)
I've seen salting on it's own doesn't work since 'John the Ripper' (http://www.openwall.com/john/) can go though a password file that has a different salt for each user and find some passwords in a few seconds. It doesn't have rainbow tables, it just tries a given password with all of the different salts and compares them. This is why you also need a strong password.
You said: "Allowing password security to depend on what the user enters IS silly"
and now you are saying: "Provided you required at least 6 characters from your users and a least one number then you can quite fairly combat the brute force approach."
Now you are saying a salting combined with a strong password policy is the solution and not either in isolation. Which I agree with.
But encrypting the passwords with a key on the server is an additional "layer of security" that doesn't actually making it harder to crack. You're just adding complexity for naught.
That doesn't necessarily mean that it's in plaintext. It could just be a 2-way encryption algorithm. That's what I did for my Twitter app pre-OAuth. That way, the passes are encrypted, but I could still decode them to send them to Twitter.
Now, the way I did it, at least, the key for decrypting it was in my code, so if someone hacked, there's a good chance that they would look through the code and figure out what the algorithm was and what the code was.
Still, if they just took the db and got out, and I fixed the hole before they realized it and came back, they would have a very hard time getting the passes.
37signals might be doing something like that, which is better than nothing. Now, they have no reason not to use a 1-way encryption algorithm, so it's still less secure than it should be.
Now, the way I did it, at least, the key for decrypting it was in my code, so if someone hacked, there's a good chance that they would look through the code and figure out what the algorithm was and what the code was.
Still, if they just took the db and got out, and I fixed the hole before they realized it and came back, they would have a very hard time getting the passes.
37signals might be doing something like that, which is better than nothing. Now, they have no reason not to use a 1-way encryption algorithm, so it's still less secure than it should be.
You said "37signals stores passwords in plain text in their database"
You have no way of knowing how they store their data! And saying something like this is ludicrous and insulting, IMHo. Sure, they emailed you your password. That doesn't mean the password was stored in "plain text"... it just means it was stored. Yes, a one way hash would be better, but they stored the password. That doesn't mean the password was not encrypted when it was stored. It also does not mean the encryption key and the storage database are not on different servers -- which would be harder to crack, since it would mean two servers would have to be compromised. There is the possibility that they used two way encryption. That exists, you know...
Just sayin'...
You have no way of knowing how they store their data! And saying something like this is ludicrous and insulting, IMHo. Sure, they emailed you your password. That doesn't mean the password was stored in "plain text"... it just means it was stored. Yes, a one way hash would be better, but they stored the password. That doesn't mean the password was not encrypted when it was stored. It also does not mean the encryption key and the storage database are not on different servers -- which would be harder to crack, since it would mean two servers would have to be compromised. There is the possibility that they used two way encryption. That exists, you know...
Just sayin'...
Occam's razor says to me that if they didn't take the time to make one-way hashes, they're not doing anything especially clever with the storage. Certainly no dual-machine way of handling them because that's surely more complicated than using SHA1 or MD5.
People are missing the point. The main reason for this is not to defend against "hackers" so much as malicious employees within the company. If you hash and salt the passwords, it's simply not possible for anyone within the organization to access them. Even if you trust all your employees, it can help in avoiding liability.
The main securityy issue is not so much that the data is in plain text if extracted - it is the fact that it can be instanlty used.
If you can only pull hashed, salted passwords from a site there is a LONG delay before you can make use of it, if at all. But with a plain text password a cracker can pull paswords, access accounts instanlty, harvest the data and potenetially ruin your site in minutes. There is no time delay in which potentially you can catch the intrusion.
The defence by delay is one of the STRONGEST defence mechanisms you can have. Every day that data is unusable to a cracker the less value it has for him/her and the more chance the intrusion will be noticed.
If you can only pull hashed, salted passwords from a site there is a LONG delay before you can make use of it, if at all. But with a plain text password a cracker can pull paswords, access accounts instanlty, harvest the data and potenetially ruin your site in minutes. There is no time delay in which potentially you can catch the intrusion.
The defence by delay is one of the STRONGEST defence mechanisms you can have. Every day that data is unusable to a cracker the less value it has for him/her and the more chance the intrusion will be noticed.
LOL, a favorite like 37signals does something so egregiously wrong, is reported, and there's plenty of security 'experts' to say no big deal. This is a HUGE deal, and thanks to the OP for pointing it out. And you call yourselves experts. Note to self, be sure to avoid writings by Thomas Ptacek, if these are his standards.
reddit made this mistake early on and they learnt their lesson. They no longer store passwords in plain text.
The popularity of a service does not guarantee that it's developers are covering all the bases.
I'm glad Django stores all the passwords as a sha1 hash.
The popularity of a service does not guarantee that it's developers are covering all the bases.
I'm glad Django stores all the passwords as a sha1 hash.
I'm glad Django stores all the passwords as a sha1 hash.
This is better than storing plaintext passwords, but it still makes a brute-force attack very cheap. Use a well designed key derivation function which is expensive to attack. (And come to BSDCan'09 next week to hear me talk about this!)
This is better than storing plaintext passwords, but it still makes a brute-force attack very cheap. Use a well designed key derivation function which is expensive to attack. (And come to BSDCan'09 next week to hear me talk about this!)
Django uses a salted hash - each password is stored with a random hash code unique to that password, e.g.:
sha1$0ae33$b8a9502237851f302170e1bb207d4eb3f36d9a31
The 0ae33 is different for each stored password, and is used as part of the SHA1 hash. This means you have to brute force each account separately - you can't just use a pre-generated SHA1 lookup table.
It sounds like you know your stuff though - if there's anything we could do to make this secure (while not depending on any libraries other than the Python standard library) please share!
sha1$0ae33$b8a9502237851f302170e1bb207d4eb3f36d9a31
The 0ae33 is different for each stored password, and is used as part of the SHA1 hash. This means you have to brute force each account separately - you can't just use a pre-generated SHA1 lookup table.
It sounds like you know your stuff though - if there's anything we could do to make this secure (while not depending on any libraries other than the Python standard library) please share!
That's still not secure, because SHA1 is very fast. To get "secure" from that, you need to iterate the function several thousand times, or use bcrypt.
Or use scrypt, which is far more secure than bcrypt. :-)
Do you have a website or blog entry which explains in detail why using bcrypt is more secure than hash+salt, and how one is supposed to properly store passwords with crypt? Is it because Blowfish is more computationally expensive, and if so, how by how much compared to SHA-1? How does it compare to using larger hashes such as SHA-512 and Whirlpool? Why Blowfish instead of AES?
The comments are impressive... pretty much all of them are people rushing to the defense of 37 Signals.
You must be new here... ;)
Anyone know if 37signals still allow people to XSS their own Basecamp accounts? http://forum.37signals.com/basecamp/forums/5/topics/3155
I haven't used Basecamp in a while, but I was distressed to discover this when screwing around with HTML in todo lists a while back.
I could put arbitrary JavaScript in the todo element, and I verified that it would execute when run by another user.
Combine that with plain text password reset and you just got pwnd bad.
I could put arbitrary JavaScript in the todo element, and I verified that it would execute when run by another user.
Combine that with plain text password reset and you just got pwnd bad.
This thread on the 37 signals site infers that the administrator of a Basecamp account has access to the passwords of that account's users. Stewart the project manager now knows your password and that of everyone else on his team...
Anyone who asserts in blanket terms that his application is secure is providing evidence to the contrary. Anyone who actually groks security won't make any such claim without loading it with carefully-chosen qualifiers.
Whilst doing hashed passwords is a no-brainer and it solves process problems like employees emailing passwords to people (who maybe impersonators) I don't think it solves all the problems with password security.
Unless you have a strong password policy, john the ripper can often find several passwords (out of 100+) in literally a few seconds by doing dictionary attack, variants and common terms. I would say that someone's hashed password should be well protected as a unencrypted one would be even inside an organization.
Unless you have a strong password policy, john the ripper can often find several passwords (out of 100+) in literally a few seconds by doing dictionary attack, variants and common terms. I would say that someone's hashed password should be well protected as a unencrypted one would be even inside an organization.
...and your both downvoting this because you believe every security problem is solved by having hashed passwords?
Another point is, do sites even protect against brute force remote hacking of passwords, Twitter for example got hacked that way.
To be clear I believe they should hash their passwords, but it's not the only measure you should take.
Another point is, do sites even protect against brute force remote hacking of passwords, Twitter for example got hacked that way.
To be clear I believe they should hash their passwords, but it's not the only measure you should take.
A long time ago I learned a technique where you use a random salt to add several bytes to a password. The salt is not stored, but rather the authenticating server does a brute-force search for it, using the user's password as a stem.
For some reason, it just doesn't seem useful to me to store the salt with the user's record, if you're worried about someone with a rainbow crack running through your password file.
Edit: that last paragraph was stupid.
For some reason, it just doesn't seem useful to me to store the salt with the user's record, if you're worried about someone with a rainbow crack running through your password file.
Edit: that last paragraph was stupid.
A long time ago I learned a technique where you use a random salt to add several bytes to a password. The salt is not stored, but rather the authenticating server does a brute-force search for it, using the user's password as a stem.
This is called "key strengthening" and was proposed by Abadi et al. in 1997. It works, but it's not as secure as key stretching using a well designed key derivation function.
This is called "key strengthening" and was proposed by Abadi et al. in 1997. It works, but it's not as secure as key stretching using a well designed key derivation function.
You lost me...the way I've always seen salts used is just before hashing, but the same salt is used for all the passwords. Then when authenticating passwords, you salt & hash the incoming password and compare to the stored record in the DB. Am I doing it wrong?
Using the same salt for all records makes it significantly easier for someone to crack your whole DB. A different salt for each row means they'd have to go through the effort of creating a rainbow table for each row instead of a whole database.
[deleted]
While it's important that the passwords aren't stored in plain text, it should be noted that it is also the last line of defense, not the first. There are plenty of other things to stop you on the way there (not having access to the email, not being able to crack into their data center, the normal stuff).
Just because passwords are in plain text it doesn't mean that suddenly everyone is in trouble.
Just because passwords are in plain text it doesn't mean that suddenly everyone is in trouble.
One of the most common ways for data to be stolen is from the inside. Having 500,000 user accounts with plain text passwords is a valuable commodity, all it takes is a pissed off employee and a SELECT email, username, password FROM users INTO OUTFILE '/tmp/users.txt'. Odds are you'd have access to tens of thousands of email addresses and from then on it's easy enough to crack tons of other accounts.
[deleted]
Very true, and a point I didn't consider.
Protect yourself against lax companies like this with the PwdHash Firefox extension. http://www.pwdhash.com/
[deleted]
Military.com is another company that stores their passwords in plain text.
obviouky. qhy da fuck not.