Reading List
Making password managers play ball with your login form from hiddedevries.nl Blog RSS feed.
Making password managers play ball with your login form
Secure passwords are long and unique. Therefore, remembering them all is impossible for most human beings. Hence the popularity of password managers. If you’re building a login form, these are some tips to improve the experience for password manager users.
With ‘playing ball’ in this post, I mean that password managers recognise your login form and let you use their features on your fields. Things like password generation, offering to save credentials for a host name and filling in the password for you in a secure way. Ideally, password managers work in both of these cases: on first time visit (when they offer to store credentials) and on recurring visits (when they let you use stored credentials).
1Password recognises it has a pair of credentials for this site
Password managers come with all sorts of heuristics to detect username and password fields. Yet, they sometimes still fail to recognise them. For this reason, Firefox’s password manager complements its heuristics with a recipe system, where users can describe specific instructions for specific hosts. I believe some password managers have hard-coded field recognition for popular websites in order to make them work.
You might think, isn’t recognising my fields the job of a password manager? Isn’t this their problem? I have good news. Mostly, yes. Password managers are built to work with all login forms that follow best practices. Doing nothing special is an option. It will often give you a form that performs well across password managers. But if things don’t play out, this post may contain some pointers to look at.
Last Pass playing ball
Security considerations
Password managers that automatically fill in credentials can be prone to coffeeshop hacker attacks (over HTTP) , as shown by Silver, Jana et al in their paper Password Managers: Attacks and Defenses (pdf). They also provided a number of measures that password managers can take to prevent this, including only allowing filling in passwords after user interaction.
There is also a risk of leaking password information to third party scripts. The article explains actions against this include having the login form on a separate domain, ad blockers, and disabling autofilling altogether (as Safari will do by default). At the same time, more transparency could be provided with browser warnings or permission requests before autofilling.
Use standard HTML form practices
Make sure your form fields are in a <form>
element that has an action
and a method
attribute defined on it.
Another think to look for, is that input
elements are associated with a label
through their ID (with for
) or by being wrapped in one.
Using the right input type can also help: type="text"
or type="email"
for the username / email address, and type="password"
for the password.
The autocomplete
attribute
The autocomplete
attribute on your username and password inputs can help password managers or browsers figure out what your fields are for. Actual autocompleting, as mentioned above, could be a security risk, if it is done by password managers on page load, rather than after user interaction, or if it happens on pages where protocol or host name are off.
Major browsers ignore autocomplete=”off”, some do this specifically for username and password fields, as they deem it more secure than users using very easy-to-remember passwords.
Google recommend using autocomplete attributes, and their advantages also appear in the spec (yes, there’s a spec!):
The
autocomplete
attribute offers a declarative mechanism by which websites can work with user agents to improve the latter’s ability to detect and fill sign-in forms by marking specific fields as “username” or “password”, and user agents implement a wide variety of detection heuristics to work with websites which haven’t taken the time to provide this detail in markup.
(Source: Credential Management spec)
For usernames
For the username field, you can add autocomplete="username"
.
For passwords
For new passwords, for example during account creation or in a password reset process, it’s autocomplete="new-password"
. For current passwords, for example in a login form, it’s autocomplete="current-password"
.
No funny stuff
Both 1Password and LastPass have various recommendations related to unexpected behaviour. Well-built login screens:
- try to stay away from dynamically adding and removing fields
- don’t regularly change names or IDs (or, worse, populate them dynamically)
- have the form on the page on first render from the server
- avoid
method=GET
and XHR requests for logging in (it can work, but it is harder) - use the
placeholder
attribute as it is intended - steer clear from mimicking a password field with a regular field so that you can do things like showing the last character
The message here is: keep it as simple as you can. This helps both users and password managers.
Multi-page login forms
Multi-page login forms can make sense, for example if there are different login options based on the type of user. With this kind of login pages, some password managers, including LastPass, may not play ball. I’ve found that LastPass will not work on first time visits, when your password field is hidden
or in a hidden
element (more on the hidden attribute). In others, including 1Password and the built-in managers of Chrome and Firefox, this problem does not exist.
In my situation, ‘pages’ were just div
s on the same page, with only one of them not hidden
. That caused LastPass to not do its first time visits thing. I consider this a bug in LastPass, or overly enthusiastic heuristics at the very least. I found out that if I used something like opacity: 0;
it did not fail. This would cause a weird user experience, as opacity
only visually hides elements, leaving them available to access by keyboard or Assistive Technologies (AT). Sometimes, and in this case, accessibility is about making something inaccessible to all, at the same time (i.e. when temporary hiding certain screens in a flow).
What I ended up going for is this: I used data-hidden
instead of hidden
, with CSS that only visually hides. In addition, I added the inert
attribute (and its polyfill, as it has no browser support), to make sure the elements are not only invisible, they are also unavailable to use (until they should). Unavailable not only visually, but also for keyboard and AT users. It’s hacky, but it did circumvent LastPass’ bug.
Conclusion
Password managers are essential to secure internet usage, so making our login fields work with them is extremely important. This will mostly happen automatically if you follow best practices. The autocomplete
attribute can make it easier for password managers to recognise your fields. Using hidden
attributes can make password managers fail altogether. This can be hacked around, but I do not recommend doing so, unless absolutely necessary.
Many thanks Job, Krijn, Mathias and Henrik for suggestions and feedback
Originally posted as Making password managers play ball with your login form on Hidde's blog.