<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Gerald</title>
    <description>The latest articles on DEV Community by Gerald (@gera2ld).</description>
    <link>https://dev.to/gera2ld</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F357562%2F606b1078-7a36-4f8e-99c1-f1a79138b59b.jpeg</url>
      <title>DEV Community: Gerald</title>
      <link>https://dev.to/gera2ld</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gera2ld"/>
    <language>en</language>
    <item>
      <title>How to Disable Autofill for Real</title>
      <dc:creator>Gerald</dc:creator>
      <pubDate>Thu, 25 Jul 2024 11:05:57 +0000</pubDate>
      <link>https://dev.to/gera2ld/how-to-disable-autofill-for-real-1411</link>
      <guid>https://dev.to/gera2ld/how-to-disable-autofill-for-real-1411</guid>
      <description>&lt;p&gt;As you may have noticed, browsers provide autocompletion and autofill for inputs.&lt;/p&gt;

&lt;p&gt;But sometimes we don't need it. For example, we know that the input is for a different value every time.&lt;/p&gt;

&lt;p&gt;Let's explore how autofill works and whether there is a reliable way to disable it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Autocomplete vs Autofill
&lt;/h2&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;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.&lt;/p&gt;

&lt;p&gt;Password managers also use &lt;code&gt;autocomplete&lt;/code&gt; to detect which value should be filled in.&lt;/p&gt;

&lt;h2&gt;
  
  
  The &lt;code&gt;autocomplete&lt;/code&gt; attribute
&lt;/h2&gt;

&lt;p&gt;Browsers offer an &lt;code&gt;autocomplete&lt;/code&gt; attribute for us to control this behavior. See &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete" rel="noopener noreferrer"&gt;MDN&lt;/a&gt; for more details.&lt;/p&gt;

&lt;p&gt;With this attribute, we can tell browsers how to fill the input. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;input autocomplete="off"&amp;gt;&lt;/code&gt; - Turn off autocomplete&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;input autocomplete="email"&amp;gt;&lt;/code&gt; - Autofill with the user's email&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;input autocomplete="one-time-code"&amp;gt;&lt;/code&gt; - A one-time password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The browser recognizes &lt;code&gt;autocomplete="one-time-code"&lt;/code&gt; so it won't try to fill it with an obviously invalid value.&lt;/p&gt;

&lt;h2&gt;
  
  
  The password manager
&lt;/h2&gt;

&lt;p&gt;The password manager has a different story.&lt;/p&gt;

&lt;p&gt;It respects the &lt;code&gt;autocomplete&lt;/code&gt; attribute to some extent. For example, it knows &lt;code&gt;&amp;lt;input autocomplete="new-password"&amp;gt;&lt;/code&gt; is for a new password, so it shouldn't be populated with the current password. But that's it.&lt;/p&gt;

&lt;p&gt;Allegedly, there was a story between the password managers and the banks.&lt;/p&gt;

&lt;p&gt;When banks realized that browsers remember passwords and autofill the inputs, they worried that the passwords could be easily breached. So they always add &lt;code&gt;autocomplete="off"&lt;/code&gt; and forced the users to input passwords by hand. As a result, users tended to set simpler passwords that they could remember.&lt;/p&gt;

&lt;p&gt;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 &lt;code&gt;autocomplete="off"&lt;/code&gt; attribute for password-related fields, particularly &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Besides that, password managers always try to be smart. So if there is no &lt;code&gt;autocomplete&lt;/code&gt; attribute for inputs, they try to figure it out themselves.&lt;/p&gt;

&lt;p&gt;It's easy to tell if there is an input for a password. We just need to find an &lt;code&gt;&amp;lt;input type="password"&amp;gt;&lt;/code&gt;. Once a password input is found, the browser will try to find an input for the &lt;code&gt;username&lt;/code&gt;. If no &lt;code&gt;&amp;lt;input autocomplete="username"&amp;gt;&lt;/code&gt; is found, it simply treats the closest input before the password input as the username input.&lt;/p&gt;

&lt;p&gt;Here are some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- `input[autocomplete="username"]` is considered the username input --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 1: &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 2: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;          &lt;span class="c"&gt;&amp;lt;!-- Password --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 3: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;  &lt;span class="c"&gt;&amp;lt;!-- Username --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- The only other input is considered the username input --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 1: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;  &lt;span class="c"&gt;&amp;lt;!-- Password --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 2: &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;                  &lt;span class="c"&gt;&amp;lt;!-- Username --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- The input right before the password input is considered the username input --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 1: &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;                  &lt;span class="c"&gt;&amp;lt;!-- Username --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 2: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;  &lt;span class="c"&gt;&amp;lt;!-- Password --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Input 3: &lt;span class="nt"&gt;&amp;lt;input&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How to disable autofill
&lt;/h2&gt;

&lt;p&gt;What if we have a password input, but don't expect other inputs to be autofilled?&lt;/p&gt;

&lt;p&gt;For example, the user has already logged in, but we expect him to re-enter the password for a sensitive action.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;One time memo: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Don't autofill me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Password: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since browsers, or rather password managers, don't fully follow our instructions of &lt;code&gt;autocomplete=off&lt;/code&gt;, we may need to find a way to cheat them.&lt;/p&gt;

&lt;p&gt;Here comes the solution: we add a hidden input and tell the browser to treat it as the username input.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;One time memo: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;placeholder=&lt;/span&gt;&lt;span class="s"&gt;"Don't autofill me"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;autocomplete=&lt;/span&gt;&lt;span class="s"&gt;"username"&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"display:none"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&amp;gt;&lt;/span&gt;Password: &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works!&lt;/p&gt;

&lt;p&gt;Note that &lt;code&gt;&amp;lt;input type="hidden" autocomplete="username"&amp;gt;&lt;/code&gt; will not work as intended since an &lt;code&gt;input[type=hidden]&lt;/code&gt; is not a normal input component and will be simply ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Autocomplete provides suggestions for past entries, while autofill fills in all recognized fields.&lt;/li&gt;
&lt;li&gt;Browsers reportedly had a fight with banks, and they decided to ignore &lt;code&gt;autocomplete=off&lt;/code&gt; for password related fields.&lt;/li&gt;
&lt;li&gt;To disable autofill for inputs, we need to use the proper &lt;code&gt;autocomplete&lt;/code&gt; attributes and may need to add a hidden input for &lt;code&gt;username&lt;/code&gt; to protect the other fields.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>html</category>
    </item>
  </channel>
</rss>
