How to Disable Autofill for Real
As you may have noticed, browsers provide autocompletion and autofill for inputs.
But sometimes we don’t need it. For example, we know that the input is for a different value every time.
Let’s explore how autofill works and whether there is a reliable way to disable it.
Autocomplete vs Autofill
Autocomplete works as suggestions, so if we input something like a username, the browser saves it and suggests the same value the next time we open this website.
Autofill works differently. It tries to prepopulate fields that the browser recognizes, such as usernames, passwords, and other form fields. This is usually done by the browser’s built-in password manager.
Password managers also use autocomplete
to detect which value should be filled in.
The autocomplete
attribute
Browsers offer an autocomplete
attribute for us to control this behavior. See MDN for more details.
With this attribute, we can tell browsers how to fill the input. For example:
<input autocomplete="off">
- Turn off autocomplete<input autocomplete="email">
- Autofill with the user’s email<input autocomplete="one-time-code">
- A one-time password
The browser recognizes autocomplete="one-time-code"
so it won’t try to fill it with an obviously invalid value.
The password manager
The password manager has a different story.
It respects the autocomplete
attribute to some extent. For example, it knows <input autocomplete="new-password">
is for a new password, so it shouldn’t be populated with the current password. But that’s it.
Allegedly, there was a story between the password managers and the banks.
When banks realized that browsers remember passwords and autofill the inputs, they worried that the passwords could be easily breached. So they always add autocomplete="off"
and forced the users to input passwords by hand. As a result, users tended to set simpler passwords that they could remember.
Password manager authors could not agree with the banks. They thought password managers could provide different and more complicated passwords for each service, so they are much more secure. And even if one password is hacked, the others remain safe. So they decided to ignore the autocomplete="off"
attribute for password-related fields, particularly username
and password
.
Besides that, password managers always try to be smart. So if there is no autocomplete
attribute for inputs, they try to figure it out themselves.
It’s easy to tell if there is an input for a password. We just need to find an <input type="password">
. Once a password input is found, the browser will try to find an input for the username
. If no <input autocomplete="username">
is found, it simply treats the closest input before the password input as the username input.
Here are some examples:
<!-- `input[autocomplete="username"]` is considered the username input -->
<div>Input 1: <input></div>
<div>Input 2: <input type="password"></div> <!-- Password -->
<div>Input 3: <input autocomplete="username"></div> <!-- Username -->
<!-- The only other input is considered the username input -->
<div>Input 1: <input type="password"></div> <!-- Password -->
<div>Input 2: <input></div> <!-- Username -->
<!-- The input right before the password input is considered the username input -->
<div>Input 1: <input></div> <!-- Username -->
<div>Input 2: <input type="password"></div> <!-- Password -->
<div>Input 3: <input></div>
How to disable autofill
What if we have a password input, but don’t expect other inputs to be autofilled?
For example, the user has already logged in, but we expect him to re-enter the password for a sensitive action.
<div>One time memo: <input placeholder="Don't autofill me"></div>
<div>Password: <input type="password"></div>
Since browsers, or rather password managers, don’t fully follow our instructions of autocomplete=off
, we may need to find a way to cheat them.
Here comes the solution: we add a hidden input and tell the browser to treat it as the username input.
<div>One time memo: <input placeholder="Don't autofill me"></div>
<input autocomplete="username" style="display:none">
<div>Password: <input type="password"></div>
It works!
Note that <input type="hidden" autocomplete="username">
will not work as intended since an input[type=hidden]
is not a normal input component and will be simply ignored.
Takeaways
- Autocomplete provides suggestions for past entries, while autofill fills in all recognized fields.
- Browsers reportedly had a fight with banks, and they decided to ignore
autocomplete=off
for password related fields. - To disable autofill for inputs, we need to use the proper
autocomplete
attributes and may need to add a hidden input forusername
to protect the other fields.