top | item 16300101

Best practices for user account, authorization and password management

321 points| mooreds | 8 years ago |cloudplatform.googleblog.com | reply

156 comments

order
[+] JoshTriplett|8 years ago|reply
> Your service should instead store a cryptographically strong hash of the password that cannot be reversed — created with, for example, PBKDF2, SHA3, Scrypt, or Bcrypt.

One of these things is not like the others, one of these things just doesn't belong

Don't use SHA3 or any other fast hash for passwords. Use a password hash designed to stymie brute-forcing, like PBKDF2, scrypt, or bcrypt.

[+] iraklism|8 years ago|reply
Million guesses per second vs thousands. Really interesting how SHA3 made its way to this blog post.
[+] jabl|8 years ago|reply
glibc crypt() uses sha512, IIRC (the thing that encrypts passwords in /etc/shadow). Iterated a number of times to make it suitably expensive.

So perhaps not as good has the bespoke password hashing functions, but not a disaster waiting to happen either.

[+] cakoose|8 years ago|reply
This is surprisingly lower quality than what you'd expect from Google.

> Your service should instead store a cryptographically strong hash of the password that cannot be reversed — created with, for example, PBKDF2, SHA3, Scrypt, or Bcrypt.

Not distinguishing between plain cryptographic hashing and password hashing is a newbie mistake.

> With that in mind, you should allow your users to use literally any characters they wish in their password.

You can't just say this without making sure people understand Unicode normalization, or they're going to get bitten later.

I realize this post is from GCP evangelism, but it's still the "Google" brand, which has a good reputation for security so a lot of people are going to trust it. I wonder if an internal product security person even reviewed it.

[+] Matt3o12_|8 years ago|reply
Can you point me to good resources to learn more about Unicode normalization especially for passwords? What are the gotchas? One the one hand, when users are allowed to enter any character, they often have difficulties to log in when they are aboard and not use their own devices. Though, I don't know if every Russian (for instance) would be able to enter a "English" password.
[+] TheAceOfHearts|8 years ago|reply
Third-party identity providers are bad for a number of reasons. My biggest issue is that none of the mentioned services make any guarantees against arbitrary account termination or lockdown. If the identity provider decides to lock you out, there's no recourse for the user. Google Accounts are notorious for this, making it nigh impossible to reach a human unless you have an engineering connection on the inside.

This post is a blatant ad for Firebase Auth. Why isn't there any mention of competing services like Auth0 and okta?

There's also lots of frameworks and libraries which handle everything for you with minimal effort. For example, you could setup something like Apache Shiro [0] as an independent service which you call out to from your app. I've seen a few different alternatives in this space, although I can't remember their names off the top of my head. They're usually written in Java, presumably because getting these features right is important for some enterprises.

[0] http://shiro.apache.org/

[+] dpcan|8 years ago|reply
I think it USED to be hard to reach a person at Google, but over the past year, for a number of various reasons I've needed to reach Google, and I've spoken with a very helpful person in every case I had, it was pretty awesome actually.
[+] trevyn|8 years ago|reply
What if you use third party auth, but keep your own account records, including email addresses?

Then if you run into any issues with the third-party provider, you just "disable" the integration and do a normal email-based password reset flow.

[+] gbacon|8 years ago|reply
Hence the additional suggestion to

4. Allow multiple identities to link to a single user account

[+] ricardonunez|8 years ago|reply
Validate email addresses before people can use your service. I lost count how many people have created accounts using my email address just because I happen to own the Gmail for my name. Banks, health records, dating sites and even students emailing me their homework thinking I am their teacher.
[+] CM30|8 years ago|reply
Okay, I'm probably going to get a fair bit of heat for saying this, but am I the only one who's never been a huge fan of letting users delete all content associated with their account at will?

I mean, in the olden days of forum software, this sort of thing was removed as a feature for a reason. Because it meant that if left uncontrolled, people could basically destroy discussions and make the site difficult to use by removing vital information from the middle of a conversation or making it hard to track whatever's going on. See for example many old Reddit topics, where you've got a long string of names saying 'deleted' and comments referencing some script that 'removes all posts to protect the user's privacy' or what not.

That's why my ideal solution has always been to basically say 'by signing up with this service, you grant us an unrevocable, unlimited right to use your posts for the purposes of the community' with a nice 30 minute or so editing window set for content. Don't like that? Well that's life I think. You can't take back emails or phone calls and you can't ask people to take your name or information out of a book or magazine once it's been available for years.

Still, maybe I'm old fashioned now.

[+] kuschku|8 years ago|reply
I suggest you read about the new European General Data Privacy Regulation, which comes into force in May 2018, and requires you to allow users to (a) export and (b) delete all personal data they gave you, including messages, posts, etc. Violation will be punished with a fine of up to 20 Million EUR or 4% your global revenue, whichever is higher. This law will apply to all sites that have EU customers, no matter where the site is located, and will be enforced globally (through banks assisting with account freezes, etc).
[+] vertex-four|8 years ago|reply
> You can't take back emails or phone calls and you can't ask people to take your name or information out of a book or magazine once it's been available for years.

None of those things are going to turn up in a Google search 20 years from now - there's a relatively limited number of people who are going to dig up this information and send it to your employer, or use it to commit crimes against you.

Privacy is not binary, as much as it's nice to think about it that way - something I've only told 2 people I trust is decidedly more private than something I've published to the world, and something I've published online and then removed is more private than something I've left up.

[+] Kequc|8 years ago|reply
One of the primary reasons I don't like posting here or on services like you describe is because I cannot delete anything. Maybe you've enough users who don't care about that but it should be taken into consideration that many people will not participate.

You'd be therefore trading direct communication for archived communication and I'm not sure that's more valuable.

[+] mrep|8 years ago|reply
> That's why my ideal solution has always been to basically say 'by signing up with this service, you grant us an irrevocable, unlimited right to use your posts for the purposes of the community' with a nice 30 minute or so editing window set for content.

Soooo, HN?

[+] aiiane|8 years ago|reply
There's a significantly higher barrier to having your personal information show up in a book or magazine (eg editors). People make stupid mistakes on social websites on the time.
[+] jwilk|8 years ago|reply
> If you must cap password length, only do so based on the maximum POST size allowable by your servers. This is commonly well above 1MB. Seriously.

Yeah, no. If someone submits a megabyte-long password, it's not because they like it super strong; it's because they're trying to DoS the server.

A sensible password length limit is probably a few kilobytes.

[+] taberiand|8 years ago|reply
And for God's sake, ensure the length checks performed at login are the same ones used on account creation. More than a few times have I been stuck at login because my 20+ character auto- generated password was silently truncated to some arbitrary length between creation and login.
[+] notfed|8 years ago|reply
Better advice: have the client pre-hash the password before sending to the server.
[+] torstenvl|8 years ago|reply
Usernames should be fully case-insensitive. It's trivial to store usernames and email addresses in all lowercase and transform any input to lowercase before comparing.

Case-insensitive comparison is not the same as convert-to-lowercase-and-compare. You should also normalize the input or you're going to set up issues where an account created on one device with one locale will be impossible to log into on another device with another locale.

[+] bzbarsky|8 years ago|reply
This part of the article is just so English-specific it hurts. It's assuming that usernames will all be ASCII, basically.

There is nothing trivial about either "lowercasing" or "case-insensitive compares" in general Unicode strings...

[+] myroon5|8 years ago|reply
Interested in this one. Could you provide a specific example?
[+] chx|8 years ago|reply
Here's my advice: do not use passwords. Just don't. If someone wants to log in, mail them a one time link. And make the session long enough this doesn't happen often -- when was the last time you needed to log into HN or Github?

We also AES encrypt the emails with the key stored on a network share. It doesn't add a lot of complexity and if an attacker gets hold of the contents of the database, they still don't have this piece of PII. It's by no means a big hurdle against any serious attack but it's nice to have.

[+] newscracker|8 years ago|reply
Edit: This is a decent enough solution, though it comes with its own pitfalls.

How exactly are you sure that the email is encrypted and is read only by the intended receiver and not by anyone else? This is too simplistic as a solution. Things like what to do if a user clicks on the same link more than once also have to be considered (is it really the intended user who clicked it or a malicious actor that the user is not aware of?).

[+] reallymental|8 years ago|reply
And how do I log into my email account to access this one time link?

Edit: Even if it's an account held on a private server, there must be a password, must there not?

[+] nnq|8 years ago|reply
> 4. Allow multiple identities to link to a single user account

Hallelujah! Finally someone like Google recommends this, so I'm no longer going to be called for crazily overengineering it every time I suggest this...

Pretty please, read points 3 and 4 from this guide and take them into consideration if you're designing any king of reusable auth-library thinggy or a framework. (If you'd also also add entity-role-based permissions so I can say "this account has role X with respect to resource Y, which grants him permissions A, B, C etc." then finally you have the minimal required imho auth/indent/perms system for your framework and I will not have to rip it off and replace it with a custom one every time, or add zillion of patches on top of it...).

[+] ryan-c|8 years ago|reply
My (probably unpopular) opinion is that passwords should be randomly generated by the service, and not possible to change to a user-selected value.

If you allow people to choose their own passwords, the vast majority will reuse them, and their account will eventually be compromised via credential stuffing.

I recognize that this solution will, at least initially, infuriate people. Letting people opt in to federated auth if they prefer that (I hate services that require it) might make it more palatable.

[+] mrep|8 years ago|reply
That pretty much requires you to use something like 1password which if hacked (your error or theirs (who knows how good some random companies security is)) then you are completely screwed as all of your accounts are now compromised. To make matters worse, you don't know any of your passwords so you cannot even log onto any of your accounts to change them (this is also a big problem if you have a customer service problem as it will lock you out of all your accounts).

I'm not a security engineer but this sets off all of my internal alarm bells when my entire identity relies on the security of 1 unrelated company that I pay a few bucks a month for.

[+] trevyn|8 years ago|reply
For services that generally "stay logged in", why have passwords at all? Just do "magic login link" emails, with some sort of 2FA if you're into that.
[+] 0x7f800000|8 years ago|reply
#1 best practice for managing passwords is: don't try to implement password management yourself because you will get it wrong.
[+] mike_hearn|8 years ago|reply
I used to work on Google's account system and wrote up a set of suggestions for how to implement user accounts on your website here:

https://blog.plan99.net/building-account-systems-f790bf5fdbe...

The advice overlaps in various areas, but is different in a few. Might be useful as another take and to see what's the same and what's different.

[+] spydum|8 years ago|reply
Great post Mike! Just wish there was a solid solution for identity providers in the enterprise space (gsuite and activeAD exist, but pretty rare). Instead every company ends up building their own IDP and making all these same mistakes. The difference is they aren't often quite as targeted for abuse (tho depends on the business).
[+] sethammons|8 years ago|reply
> SMS 2FA auth has been deprecated by NIST (https://pages.nist.gov/800-63-3/sp800-63b.html) due to multiple weaknesses, however, it may be the most secure option your users will accept for what they consider a trivial service.

I skimmed through the NIST document and couldn't find that claim.

> [5.1.3.1 allows if] sent from the verifier to the out-of-band device via the PSTN (SMS or voice).

Maybe it is interpreting this part from the same section?

> the device SHOULD NOT display the authentication secret while it is locked by the owner

So it seems to me that SMS is not deprecated but open to issues if the SMS shows the secret. I looked a little deeper in the doc. Section 5.2.10 on Restricted Authenticators lays out that devices could become restricted as times change, but I couldn't find where the doc actually says 2FA over SMS is now restricted.

The post claims that users may allow SMS for trivial services, but does not call out what that means. I don't use more than a password manager for trivial services (forums and the like), and I use 2FA over SMS for things that might have financial details (if 2FA is an option).

The rest of the article makes sense, but I'm having trouble with this one point. Did I miss something in the NIST document? And if 2FA over SMS is out, as a website with billing, should one look at using an authenticator like Duo? The author says to just auth via Google et al, but that feels like kicking the can down the road hoping they or Twitter have something better than 2FA over SMS.

[+] pgodzin|8 years ago|reply
> Allow users to change their username

Does Google allow me to change the username of my elementary-school aged gmail account?

[+] balladeer|8 years ago|reply
They also say this:

> Don't impose unreasonable rules for usernames

On Google+ the selection of vanity URL is such a master stroke of tragedy that it hurts to think whether the restrictions are idiotic or just incompetent.

They already have decided the first part of your username for you: <base_url>/FirstnameLastname........

Yes, You only get to choose the last part of your username - the first part is decided. Even though "Firstname, or "Lastname", or "FirstnameLastname", or anything else that you want to choose is available, you can't choose them - unless you are famous enough or possibly you know someone at Google. The latter, I believe, is also very useful if you happen to lose access to your Google account.

After trying twice I just deleted Google+ from my Google a/c.

[+] zerr|8 years ago|reply
Do not tell them this, they will completely disable your account.
[+] secabeen|8 years ago|reply
> Do not store plaintext passwords under any circumstances.

I really wish the original EAP-TLS specification had had some support for passing passwords across the TLS session. Certificates are great, but so few places provided them, and everyone who wants to easily support Windows 7 machines on the WPA2-Enterprise system has to store plaintext passwords on the server to support MSCHAP-V2.

EAP-TTLS finally did solve that problem, but with Windows 8. When Windows 7 finally dies, one of the first things I'm going to do is discard the plaintext passwords in my authentication databases.

[+] mygo|8 years ago|reply
You store plaintext passwords? Interesting... where do you work? What’s your tech stack? Oh and what’s your name? ...
[+] mindcrime|8 years ago|reply
This is timely as I am literally just getting into working on the account management / login / registration stuff for a new app tonight. Most of this stuff isn't really new, but it's good to have a reminder, and/or validation of certain things.

We're not (currently) doing 3rd party providers like Google / Twitter / Facebook, but since we have (well, will have) multiple independent apps out there, we have a CAS[1] server set up for SSO and all our apps use that for authentication.

This current app is a little more complicated to deal with, since it's basically an "app for provisioning apps". So we have "login to the main site" level login, and then login / authorization for the stuff that gets provisioned. We also want to support things like "invite a user to join via email", etc. Still working on how exactly the user experience will work on some of these scenarios.

[1]:https://github.com/apereo/cas

[+] privacypoller|8 years ago|reply
>> 8. Let your users delete their accounts

Man, if I was drinking milk I would have shot it out my nose at that one. Google and every single social network are the last actors who make it easy (or even let you for-realize-ies) delete your association. They may let you remove access to the persona they store and monetize, but they certainly don't let you "easily delete your account". THis entire post is a giant crock.

[+] kj65557|8 years ago|reply
(also work for google)

It is pretty easy to delete your account on many social networks. The following support deletion:

* Google (all account data)

* Facebook (all account data except messages that others have received)

* Reddit

* Instagram

* Snapchat (requires you to "deactivate" for 30 days)

One thing that is confusing is that many websites also have a "deactivate" feature. Some users may confuse the two and mistakenly think "deactivation" is the same as "deletion".

[+] jasonkostempski|8 years ago|reply
I hope someone at HN is listening to that recommendation.
[+] raarts|8 years ago|reply
Using Google and Facebook for your user's login is easy and safe. It's when programmers create there own login process where true problems arise.

Does anybody have any data on the percentage of users that refrain from using Google/Facebook and always create email accounts?

[+] marknadal|8 years ago|reply
Even better best practices: Don't let the server be able to derive the password at all. Have fully P2P user accounts that use PBKDF2 to extend passwords into proofs that can client-side only decrypt public/private keypairs. For an example, see: https://github.com/amark/gun/wiki/auth