This is a nice list, but it misses one of the most important features in my opinion: Allow users to paste username/password. This seems like such an obvious thing, and it's also the default behavior. But for some inexplicable reason, some product managers seem to be under the assumption that disallowing pasting of passwords enhances security. This is obviously false, and will just lead to your users choosing worse passwords.
And make it possible to have password managers auto-type the username and password. Some sites don't focus the password field after the username field and so the "username -> tab -> password -> enter" auto-typing breaks.
In one especially bad case I encountered, the tab key after the username would focus on a "clear username" button which appears after entering the first character of the username. So the auto-typing of the password manager would enter the username, tab to the button, enter a password into the void and then click the username reset button, leaving the login form empty. Who needs a button to clear the username field in the first place? That's seems so useless to me.
One thing that I have seen as a trend on some websites that I hate is when they first show you the Email field, and you have to press next, and then they ask you for the password.
That is done by evernote IIRC. Why? Just show me both fields.
I run a company offering form analytics [0] so I have seen plenty of real data on how people use forms. One stupid issue I've seen over and over again is a lack of trimming of email/username/password strings, say:
One thing I read (and checked, this was in the past) Facebook did was even do simple white stripping on passwords, as well as checking with caps-lock switched on.
While it technically might make passwords very slightly less secure, it makes life much easier for users, so I personally think it's worth the cost.
1) Do not limit the length of the password to some arbitrarily small number.
2) Do not validate email beyond the simplest, "includes an @ and a period. Email is validated by sending a confirmation link.
3) Don't get so stupid with the "secure password" special character crap. Some of us use super long, but memorable passwords, which are more secure than your bull#@!+&$
PCI DSS compliance is shit at this. Enforced 90 day cycles, mixed casing, alpha, numeric, and "special" characters. The only halfway sane policies they enforce are must not match username, and mustn't be a dictionary word (singular), and minimum length of 7.
1) Do not limit the length of the password to some arbitrarily small number.
I got bit by this recently.
I decided to update my Bank of America password, and so generated a 30-character password.
Bank of America's password change page accepted the 30 character password. But then I couldn't log in because Bank of America's login page won't allow passwords longer than 20 characters.
I ended up having to call Bank of America on the phone and the rude web site tech guy said that he's been there 10 years, and 20 characters has always been the limit.
1 - If that's true, then don't let me change my password to 30 characters.
2 - Why would a bank insist on a password scheme that is clearly LESS secure than a reasonable alternative.
There was a django security issue where password length lead to a possible DOS attack against the server. So now they limit passwords rather arbitrarily to 4096 bytes.
> Every single labelled text input you ever create should have clickable labels. It’s a wonder this isn’t done by HTML by default
This is done by HTML by default, if you use the for="" attribute or nest the input in the label.
> No user should have to guess at what the password requirements are. Show them when they’re relevant (P.S. And remove them when they’re not).
Or, just always show them. It's hard to make them accessible if you can only see them when the field is focused.
> Let users see their password
This is arguably an antipattern. If this was a best practice, it would be baked into the browser. Encouraging password manager use (every browser comes with one built in!) is what we should be aiming for. "Confirm password" fields prevent the problem that the post tries to avoid, and it's really not "onerous". Or, use something like WebAuthn.
> If this was a best practice, it would be baked into the browser.
Edge already support it for any password input. Yes it's better to be supported by browser, but it not mean not good to be implemented by website. How "Confirm password" solution better? It's completely redundant for password manager user. It also won't help from CAPSLOCK.
There are so many fails when it comes to signup/password change/logon UI that I’ve become acutely aware of after sitting next to an elderly couple trying to implement 1password.
Validate that your passwords match immediately, yes, but be aware that the password fields may be filled in / altered by a process other than typing a character! How do you describe to a non tech user that the only reason the new password and confirm password fields are actually the same (even though there’s an error) and to proceed your only option is to hit space bar in one of those fields and blindly delete it. Then it updates the validation and you can proceed?
Along the same lines- sites that don’t let you paste in your password from a password manager. What’s worse - not letting you paste in only to “confirm” your password. What’s the point of that?
Just finding the account page to change your password is super confusing. There’s typically a little user icon in the top right so I have shown them that. But after that, sometimes it’s in “profile” - other times “security” - and other times it’s hidden under a few levels of menus. Some sites call the password a “passcode” - and on and on.
Password complexity requirements have gotten out of hand. “At least one symbol but not more than four, two of which can repeat - and only the symbols @ and ! Allowed”. Really?? Now I have to specially tweak the password automatically generated by 1password to match. Again, explain that to your grandma.
SMS/2fa prompts using a password field - whenever you fill one in, it prompts 1password to helpfully remember that password for you. Super confusing for a non tech person! Now they’re potentially adding a ton of new “passwords” for this website into the password manager, and they have no idea which one to use when logging in again.
Email “validation” - I gave up using my personal non gmail address for sites as most of them claim that the non standard tld I used was not “valid”.
For the password requirements, I would actually always show them as a list of bullet points (length, casing, special character, number, no name…) which would validate on change, from a list of red crosses to a list of green checks.
One thing that hasn’t been mentioned in the article is l, if you’re doing online validation (on change, on blur, and on focus), if the submit button of the form should be disabled as long as the form isn’t completely valid.
I don't think the bulletpoint list of requirements is that relevant anymore; instead, I'd give a live updating password strength indicator and reject anything "weak" or "medium". That way, the user can themselves decide on symbols and letters or length. A check on commonly used passwords should also be included of course.
My nomination - when someone has been invited by email to join the site (e.g in a saas system, one user invites someone else to join their team), then don't make them verify their email!
I see this so often, and it adds no security, and bewilders the user.
When someone clicks through from an invite email, you can assume that they have control of that email so slip email verification, and just ask them for their password.
We modified keycloak to do this and it greatly reduced support calls. It's a mystery to me why it's not out of the box behavior.
Ehhhh, that may not be the email address that the invited user prefers to use (or may not even know what email it was).
For example, in my last (extremely large) company, IT would helpfully create multiple email addresses for us (UUID plus firstname.lastname) and you could also ask them to create one that you're used to using. So if someone emailed me at work, it was not obvious which email they used and if I then needed to use those credentials to login on a different device, I wouldn't know what to use.
> My nomination - when someone has been invited by email to join the site (e.g in a saas system, one user invites someone else to join their team), then don't make them verify their email!
Password reset emails usually expire after a short time for security reasons. Maybe the extra verification step when accepting the invite is for similar reasons when the invitation isn't accepted quickly? Unlike for password reset emails, you can't assume invitation emails are likely to be opened soon after being sent either.
Hmm, but what if I generated a signup email in your name and signed you up for something you didn't want. Seems like a good way to enable harassment and spam.
Tip from me: If the user tries to visit a specific URL and they have to log in first, redirect the user back to the original URL once they've logged in instead of sending them to some generic account page. It's super annoying and disorientating otherwise.
Oh I worked at a company where the primary B2B website was like that. The login had been created in PHP by some folks who were really good at the relatively complex business domain, but thought "just throw a login screen up" was good enough security. For services where the customers spend hundreds of thousands of dollars. There were a handful of predetermined landing pages, depending on what "type" of user you were, and deep linking generally didn't work.
OTH I see this more with SPAs, because there's not really a "page" to redirect back to, just a bunch of browser-local React state that shouldn't be trusted across authentication boundaries.
"2. Use specialized mobile keyboards" is a bit confusing. Should be type=email of course for email, which should by default sort out "3. Validate fields immediately"
I feel browsers should do "6. Let users see their password", not the Web app.
It would be really good to see RFC 5233 local-part filtering characters (e.g. '+') being permitted in the validation for email addresses on this list. It's much less of a problem these days, but the number of times a sign up form has flat out refused to accept these as valid - or worse the sign up process accepted it, but the login simply doesn't work!
> Note: also applies to telephone numbers (type=tel), URLs (type=url), and numbers (type=num) in your signup flow
While this sounds great advice for telephone numbers in theory, but in practice browsers on Android replace the normal keyboard with a big number keyboard without any "autocomplete".
So the end result is when a designer makes input(type=num) I actually have to fill in my whole phone number by hand as opposed to using the autocomplete which shows my phone number as soon as I enter the first 2 digits. I guess it's partly android's keyboard fault for hiding autocomplete suggestions on whim.
I've had terrible results with using an <input type='date' ... /> for choosing the birth date of users on a registration form. iOS would make this awesome control where I could scroll and choose the date in a nice way, but on Android, the control was just horrible and we kept getting complaints.
In the end, we choose the [day][month][year] dropdown set because it was the only one that didn't drive our users crazy. I really loved the iOS control though.
Does anyone know why certain sites e.g. Amazon, split their username and password forms into two differe pages. It makes it a bit more annoying to use something like KeePass.
It handles cases where Single Sign On is supported. User enters their email and then is redirected to their company’s login provider to complete the login.
However, there are some accessibility concerns. Screenreader users may be dumped into a form field without context and/or explanatory content, which may have preceded the form field and may be essential. Sometimes it's still best to let users decide, when they are ready for a specific interaction.
No, it isn't for the users to decide, if they are already on a login page they will fill the login field first in nearly all cases.
That screenreaders are crap doesn't excuse breaking flow for 99.9% of users. Autofocus is essential for the ergonomy of all single-purpose forms, be it a search form, login form or order form. The first form field a user will interact with NEEDS autofocus.
On 11.: also prevent leaking the account’s existence when someone requests a password reset. Otherwise it’s a great way of finding out who has accounts where if you know their email. Use the same text as receipt to the user after form submission.
You can, and probably should, go one step further and serve the same HTTP-response (size in bytes and response time) as well.
#9 in particular. One would think that after a week or two of dealing with all the problems related to a username (having to be unique across all users, having to have a forgot username form, etc.), one would realize the value in a naturally unique and easy to understand value like an email address. But in spite of this, the use of usernames abound.
He points out that this should probably be done on blur which means after you’ve left that input it’ll validate. This is much better than waiting until you submit.
#10, If the user guesses an invalid password, say why it’s invalid.
Failed login should not say anything more than necessary. If the user enters a valid email and the wrong password, just say "invalid login". If you're going to display the password requirements, do so always, or don't do it at all.
The problem is that a malicious party could try usernames until they get "the password is incorrect for that user", and now they have a valid login. This is especially bad if the login is email, because now they have a valid email address to spam, and possibly phish the password.
Sometimes being too helpful is bad security. It's always a tradeoff, but something as simple as not giving away information protects both the user and the service way more than a bit of confusion.
I've always wondered why there is even a distinction between Log in and Sign up at all. Surely if the user is logging in with their email address, the app can decide whether they're new or existing? What benefit does splitting it into two identical-looking forms provide?
[+] [-] sakarisson|4 years ago|reply
[+] [-] dthul|4 years ago|reply
In one especially bad case I encountered, the tab key after the username would focus on a "clear username" button which appears after entering the first character of the username. So the auto-typing of the password manager would enter the username, tab to the button, enter a password into the void and then click the username reset button, leaving the login form empty. Who needs a button to clear the username field in the first place? That's seems so useless to me.
[+] [-] marcus_holmes|4 years ago|reply
[+] [-] alexaholic|4 years ago|reply
[+] [-] kwanbix|4 years ago|reply
That is done by evernote IIRC. Why? Just show me both fields.
[+] [-] mixedCase|4 years ago|reply
[+] [-] bttrfl|4 years ago|reply
'[email protected] '
resulting in errors like 'invalid email'. Since whitespaces are invisible to users, they can't figure out what's wrong.
[0] https://www.useitbetter.com/features/form-analytics/
[+] [-] CJefferson|4 years ago|reply
While it technically might make passwords very slightly less secure, it makes life much easier for users, so I personally think it's worth the cost.
[+] [-] lbayes|4 years ago|reply
1) Do not limit the length of the password to some arbitrarily small number.
2) Do not validate email beyond the simplest, "includes an @ and a period. Email is validated by sending a confirmation link.
3) Don't get so stupid with the "secure password" special character crap. Some of us use super long, but memorable passwords, which are more secure than your bull#@!+&$
[+] [-] _0ffh|4 years ago|reply
[+] [-] Jenk|4 years ago|reply
[+] [-] reaperducer|4 years ago|reply
I got bit by this recently.
I decided to update my Bank of America password, and so generated a 30-character password.
Bank of America's password change page accepted the 30 character password. But then I couldn't log in because Bank of America's login page won't allow passwords longer than 20 characters.
I ended up having to call Bank of America on the phone and the rude web site tech guy said that he's been there 10 years, and 20 characters has always been the limit.
1 - If that's true, then don't let me change my password to 30 characters.
2 - Why would a bank insist on a password scheme that is clearly LESS secure than a reasonable alternative.
[+] [-] jmilloy|4 years ago|reply
[+] [-] cratermoon|4 years ago|reply
Full stop. Require email confirmation to complete signup. If the address can receive email, it's valid, it doesn't matter what's in it.
[+] [-] shezi|4 years ago|reply
https://www.djangoproject.com/weblog/2013/sep/15/security/
[+] [-] ecesena|4 years ago|reply
[+] [-] quesera|4 years ago|reply
Periods are not required, either!
[+] [-] cnlevy|4 years ago|reply
[+] [-] GrumpyNl|4 years ago|reply
[+] [-] bastawhiz|4 years ago|reply
This is done by HTML by default, if you use the for="" attribute or nest the input in the label.
> No user should have to guess at what the password requirements are. Show them when they’re relevant (P.S. And remove them when they’re not).
Or, just always show them. It's hard to make them accessible if you can only see them when the field is focused.
> Let users see their password
This is arguably an antipattern. If this was a best practice, it would be baked into the browser. Encouraging password manager use (every browser comes with one built in!) is what we should be aiming for. "Confirm password" fields prevent the problem that the post tries to avoid, and it's really not "onerous". Or, use something like WebAuthn.
[+] [-] fomine3|4 years ago|reply
Edge already support it for any password input. Yes it's better to be supported by browser, but it not mean not good to be implemented by website. How "Confirm password" solution better? It's completely redundant for password manager user. It also won't help from CAPSLOCK.
[+] [-] ipython|4 years ago|reply
Validate that your passwords match immediately, yes, but be aware that the password fields may be filled in / altered by a process other than typing a character! How do you describe to a non tech user that the only reason the new password and confirm password fields are actually the same (even though there’s an error) and to proceed your only option is to hit space bar in one of those fields and blindly delete it. Then it updates the validation and you can proceed?
Along the same lines- sites that don’t let you paste in your password from a password manager. What’s worse - not letting you paste in only to “confirm” your password. What’s the point of that?
Just finding the account page to change your password is super confusing. There’s typically a little user icon in the top right so I have shown them that. But after that, sometimes it’s in “profile” - other times “security” - and other times it’s hidden under a few levels of menus. Some sites call the password a “passcode” - and on and on.
Password complexity requirements have gotten out of hand. “At least one symbol but not more than four, two of which can repeat - and only the symbols @ and ! Allowed”. Really?? Now I have to specially tweak the password automatically generated by 1password to match. Again, explain that to your grandma.
SMS/2fa prompts using a password field - whenever you fill one in, it prompts 1password to helpfully remember that password for you. Super confusing for a non tech person! Now they’re potentially adding a ton of new “passwords” for this website into the password manager, and they have no idea which one to use when logging in again.
Email “validation” - I gave up using my personal non gmail address for sites as most of them claim that the non standard tld I used was not “valid”.
[+] [-] bbx|4 years ago|reply
For the password requirements, I would actually always show them as a list of bullet points (length, casing, special character, number, no name…) which would validate on change, from a list of red crosses to a list of green checks.
One thing that hasn’t been mentioned in the article is l, if you’re doing online validation (on change, on blur, and on focus), if the submit button of the form should be disabled as long as the form isn’t completely valid.
[+] [-] Cthulhu_|4 years ago|reply
[+] [-] beachy|4 years ago|reply
I see this so often, and it adds no security, and bewilders the user.
When someone clicks through from an invite email, you can assume that they have control of that email so slip email verification, and just ask them for their password.
We modified keycloak to do this and it greatly reduced support calls. It's a mystery to me why it's not out of the box behavior.
[+] [-] sib|4 years ago|reply
For example, in my last (extremely large) company, IT would helpfully create multiple email addresses for us (UUID plus firstname.lastname) and you could also ask them to create one that you're used to using. So if someone emailed me at work, it was not obvious which email they used and if I then needed to use those credentials to login on a different device, I wouldn't know what to use.
[+] [-] seanwilson|4 years ago|reply
Password reset emails usually expire after a short time for security reasons. Maybe the extra verification step when accepting the invite is for similar reasons when the invitation isn't accepted quickly? Unlike for password reset emails, you can't assume invitation emails are likely to be opened soon after being sent either.
[+] [-] cratermoon|4 years ago|reply
[+] [-] seanwilson|4 years ago|reply
[+] [-] cratermoon|4 years ago|reply
OTH I see this more with SPAs, because there's not really a "page" to redirect back to, just a bunch of browser-local React state that shouldn't be trusted across authentication boundaries.
[+] [-] jpalomaki|4 years ago|reply
[+] [-] hendry|4 years ago|reply
I feel browsers should do "6. Let users see their password", not the Web app.
Could probably be improved by https://html.spec.whatwg.org/#autofilling-form-controls:-the...
Some simple HTML on display would be nice.
[+] [-] fomine3|4 years ago|reply
This! I spent 1s for every Sign In because I'm non native.
Also add: 0. Don't obscure login path. Some websites shows big sign up form or link on top page, but shows small login link.
[+] [-] adamdoran|4 years ago|reply
[+] [-] superasn|4 years ago|reply
While this sounds great advice for telephone numbers in theory, but in practice browsers on Android replace the normal keyboard with a big number keyboard without any "autocomplete".
So the end result is when a designer makes input(type=num) I actually have to fill in my whole phone number by hand as opposed to using the autocomplete which shows my phone number as soon as I enter the first 2 digits. I guess it's partly android's keyboard fault for hiding autocomplete suggestions on whim.
[+] [-] ThalesX|4 years ago|reply
In the end, we choose the [day][month][year] dropdown set because it was the only one that didn't drive our users crazy. I really loved the iOS control though.
[+] [-] raspyberr|4 years ago|reply
[+] [-] ec109685|4 years ago|reply
[+] [-] masswerk|4 years ago|reply
However, there are some accessibility concerns. Screenreader users may be dumped into a form field without context and/or explanatory content, which may have preceded the form field and may be essential. Sometimes it's still best to let users decide, when they are ready for a specific interaction.
[1] https://medium.com/@gavyn/til-autofocus-inputs-are-an-access...
[2] https://brucelawson.co.uk/2009/the-accessibility-of-html-5-a...
[+] [-] corty|4 years ago|reply
That screenreaders are crap doesn't excuse breaking flow for 99.9% of users. Autofocus is essential for the ergonomy of all single-purpose forms, be it a search form, login form or order form. The first form field a user will interact with NEEDS autofocus.
[+] [-] Kiro|4 years ago|reply
[+] [-] henrikwm|4 years ago|reply
You can, and probably should, go one step further and serve the same HTTP-response (size in bytes and response time) as well.
[+] [-] mbostleman|4 years ago|reply
[+] [-] leokennis|4 years ago|reply
I am 35, not 8. Just say "This is not a valid email address".
[+] [-] dinkleberg|4 years ago|reply
[+] [-] cratermoon|4 years ago|reply
Failed login should not say anything more than necessary. If the user enters a valid email and the wrong password, just say "invalid login". If you're going to display the password requirements, do so always, or don't do it at all.
The problem is that a malicious party could try usernames until they get "the password is incorrect for that user", and now they have a valid login. This is especially bad if the login is email, because now they have a valid email address to spam, and possibly phish the password.
Sometimes being too helpful is bad security. It's always a tradeoff, but something as simple as not giving away information protects both the user and the service way more than a bit of confusion.
[+] [-] g105b|4 years ago|reply
[+] [-] mhitza|4 years ago|reply
If on such a form you output something like, "a user with this email address already exists", bots with targeted email could scan for site accounts.
On the other hand on a separate login form, you can always output "invalid credentials" on non matching email or password.
[+] [-] ec109685|4 years ago|reply
That said, fast.co does this to streamline their flows.