I've just finished creating two FAQs: One for developers who come to the site and don't understand what's wrong with what they're doing [2] and another for the laymen who want to understand what we're all about and how to protect themselves [3]. The idea is that people could also send these links around to educate others.
As HN is one of our main supporting communities, I'd love to hear your thoughts about both of these new pages.
[1] http://plaintextoffenders.com/ [2] http://plaintextoffenders.com/faq/devs [3] http://plaintextoffenders.com/faq/non-devs
This is one I always struggled to understand. If email is compromised, the attacker can request and immediately intercept a password reset anyway.
[edit: Many excellent points below. I think some of these should be in the FAQ.
That said, it can be more secure. Firstly, people reuse passwords, so intercepting a plaintext password gives you access not only to the account on that site, but also several others.
Secondly, if the link expires you can't use old account recovery emails to find out passwords. If you manage to compromise an account (rather than mitm), you can search through for old "here is your password" emails and use those without even having to initiate a new password recovery process, which in this age of mobile devices and push notifications risks the victim seeing the email and getting suspicious.
It's totally irresponsible for a service provider to essentially reveal a secret like that (without asking or really, ever).
Additionally, even if your reset request is harvested via MITM, if you use a single-use reset token, and an attacker uses it before you can, you know something is up. Even if it's not single-use, your password suddenly no longer working should ring alarm bells.
No, the people who use a common password gave out the keys.
There is simply no excusing it. The apologism for it has to stop. NEVER use the same password across multiple services. If one service gets compromised, the extent of their culpability is their own service. Anyone whose password exposes other things was the cause of their own demise.
EDIT: I will not back down from this (and you shouldn't feel too ashamed for reusing passwords and falling in the above buckets, desperately hitting down arrow. Just correct your mistakes). It is utter idiocy to constantly defend the habit of shared passwords, when people give it to services of zero trust, and with unknown habits and practices. When some service of no consequence stores your password in plaintext, that is them being dumb. If you then complain because it's the same password used elsewhere, that is you being dumb.
This would close the "I accidentally left my account logged in" hole.
Also, after users learn the new process, it opens up a new phishing attack vector for Gmail.
> Email is not a secure medium. It was never designed to be one. It’s susceptible to Man In The Middle (MITM) attacks and a slew of other issues.
Email by default right not isn't encrypted. Anyone (eg, a 3-letter government agency or a malicous actor on an unencrypted wifi network) who can intercept your traffic can read that password - and you can't even tell. At least with a password reset there's the "notification" of "my password doesn't work anymore". That's mitigated by SSL/TLS, but it's still an important point to consider.
Not really the main issue - if you always send the password the Thief controlling the email does not even need to reset the password. he can get in without leaving any trace at any time. It also allows the collection of all the Passwords from all the users in bulk. And if your users are reusing their passwords everything else is open too.
Sending the Password is just a stupid policy. Its up there with restrictive Password requirements and Server-side unhashed Password storage.
- Request password reset.
- Sniff email with reset link.
- Go to reset link before user does and change password.Still, one time use password reset links with explicit instructions and set expectations to reset the password immediately is the way to go if you're emailing anything IMO.
Basically you could visit a malicious webpage, and all emails containing the word "password", would be sent to the attacker.
Whenever I encounter them, I paste the output of "dd if=/dev/random bs=1k count=1 |uuencode x" into the field.
I had a password for a credit card account which could not be more than 8 characters and couldn't contain 'special' characters or punctuation. This was probably done to either make the password human readable (over-the-phone, horrible idea), or because of some legacy system on their end. At some point the organization got smart and made a minimum of 6 characters, of which two needed to be numbers (but kept the other restrictions). This effectively narrows down pool the possible passwords for an attacker to guess, the opposite of what you want to do.
Originally:
36^8 + 36^7 + 36^6 + 36^5 + 36^4 + 36^3 + 36^2 + 36
2,901,713,047,668 possible passwords
~41.4 bits
After: (36^8 - 26^2 * (8*7)/2) + (36^7 - 26^2 * (7*6)/2) + (36^6 - 26^2 * (6*5)/2)
2,901,650,810,624 possible passwords
still ~41.4 bits
Only 62,237,044 possibilities eliminated. Length is the most important factor, so this was probably a good decision if most of their users were using <= 6 char passwords, or not using numbers at all. And frankly, the financial sector should be using HSMs anyway, making weak KDFs irrelevant.I sucks for people that generate individual passwords based on a common password and site-specific data.
In the old days, if you stored the unencrypted password, it had to have a maximum length because somebody decided to make the db column 16 chars....
Same goes for charset limitations (e.g. try storing unicode characters in a database set to US-ASCII charset...) - with a hash your input does not matter - it is just a sequence of bytes that are hashed.
Lastly, the source of disallowing certain characters is the laziness of the implementers that couldn't be bothered to implement proper input encoding in their frontend
edit:
Maybe something along the lines of:
> Modern cryptography allows websites to save passwords in a form that is un-decryptable even to the site itself. This works because to check the validity of logins, the unencrypted (plain) version of the password is never needed. The fact that a site stores the password in a decryptable format and decrypts it to show it to you means that an attacker could potentially decrypt the password in the exact same way. Or even worse, maybe they never encrypt it in the first place! This potentially compromises the safety of the password you use because it lets an attacker steal your password.
> If the website can pull out your password to show it to you, an attacker can pull out the password to steal it.
As ever, the issue is explaining hashing.
Ordinary people are going to be thinking about a key in a lock. Does the lock on your house store the key inside? Maybe in some kind of information-theoretic sense but in the ordinary meaning of the word, no, it has a representation (that may not even be sufficiently specific to recover your key exactly). And if you lose your key you don't break into the lock to recover it--you call a locksmith to replace the lock, and get new keys.
That right there is an intuitive understanding of both hashing and good security principles that goes surprisingly far.
"It is possible to store passwords in a way that the website cannot see your password, but can still verify that a password entered by you checks out." (trust us, after all you're trusting that we know what we're talking about by reading this stuff)
https://docs.djangoproject.com/en/dev/topics/auth/passwords/
A list of password hashers, on successful login the user is upgraded to the top password hasher. Makes it very simple to switch to a new scheme or work factor.
hash = CryptContext(
# upgrading from an md5_crypted system
["sha256_crypt", "md5_crypt"],
deprecated=['auto'])
# in auth code
valid, updated = hash.verify_and_update(password, current_hash)
if not valid:
# error out
if updated is not None:
# updated is the new hash to set in database
[0] https://pythonhosted.org/passlib/[1] https://pythonhosted.org/passlib/lib/passlib.context.html?hi...
I'm not saying we shouldn't take care of our users, but how's our fault that their email is hacked? We can't do anything to protect against this and placing more complex policies would hurt users who have enough common sense to this properly and expecting the same from us.
P.S. I'm in no way saying to to ditch all security procedures we can, but to one point security is about trust, and if you can't trust your users to keep their freaking passwords and email accounts secured, then hell with them. Put it in plain text in your TOS and be done with it.
You could as well just publish your users passwords at your front page, and claim that if a user has a password compromissed because of that, it's his own fault, you should be able to trust them not to use insecure services.
By the way, you can always allow users to connect several OpenIDs to a single account – this way, worried users can provide redundancy themselves, if desired.
My dad is an endodontist with zero software/web experience and even he knows not to keep passwords in plaintext and to use ssl.
I'm only a CS undergrad and I'm learning webdev so I can implement it for him but I still know to hash and salt your passwords. The fact that people implement these critical systems (and get paid for it) without knowing basic practices makes me worry about the future.
Question 9 should include a sub-section .3 which explains that if you unrestrict the password field, you need to include a basic password cracker or strength requirement, usually along with a client-side "strength" meter. The backend should reject all simple passwords and the frontend should help the user pick a simple yet strong password.
And ideally this page would also link the dev to http://twofactorauth.org/ as an example of how many more places are implementing 2FA. Passwords are dead; long live passwords with 2FA.
Re: Q9. Again, that's a great pattern, but is not a requirement to not be on our list.
This is linked to from the non-dev FAQ, but I'll make sure to add a section about 2FA to the dev section.
Thanks!
[1] https://tech.dropbox.com/2012/04/zxcvbn-realistic-password-s...
Something to arm the devs who work at these places with something when they go to management who's reaction is "yeah I know it's bad.. but... like, we have important shit to do."
Example:
>7. Fine, but I still get to send users their passwords once they created them so they don’t forget them, right?
No, Email is not a secure medium.....
By citing an inside-baseball controversy, you're making it harder for developers to do a good job storing passwords, because you're creating the impression that developers need to carefully choose which password hashing algorithm they use, and be careful about making the wrong choice.
In reality, what developers need to be careful about is choosing a password hashing algorithm, and not a general-purpose cryptographic hash. The right message is that PBKDF2, bcrypt, and scrypt are all fine options.
So my feedback is that your developer FAQ is trying to be a little too clever for its own good. I'd revise it.
http://nakedsecurity.sophos.com/2013/11/20/serious-security-...
"We explain in everything our About page." - doesn't read right, maybe 'we explain everything on our About page"?
"your post was deleted with prejudice" ?? needs rephrasing
2. Rephrased.
Is this offending? Let's also pretend that I have to change this password upon my first login.
Wouldn't anyone intercepting the email be able to use the reset link themselves and gain access to the account?
Providers should send you notifications when you reset your password, they generally don't when you just log-in like normal.
:)
[1] http://plaintextoffenders.com/ [2] http://plaintextoffenders.com/faq/devs [3] http://plaintextoffenders.com/faq/non-devs
I'd remove the emphasized text. Yes they are vulnerable to collision attacks but that's completely irrelevant in this context.
EDIT: Just saw @ajanuary's child comment on the top-voted parent. The point exactly.
MD5 and SHA1 are bad for password hashing indeed, but that's because they're fast, not because they have known collisions.
Collision attack has nothing to do with password security. For passwords the relevant attack is the preimage attack, which is a different thing and there are no feasible preimage attacks against these hashes (yet, of course).