Search code examples
htmlformsauthenticationtotp

Correct HTML code to enable autofill of TOTP input by password managers


There are quite a few password managers claiming to help the user by automatically filling in the 2FA token (TOTP) code normally generated by something like Google Authenticator. This should work very similar to how they manage to auto-fill the user name and password.

I cannot figure out how to code my HTML form to get them to auto-fill the TOTP field.

My HTML form currently looks something like this:

<form id="login-form" action="login" method="post">
  <div>
    <label for="login-username" class="form-label">E-mail address</label>
    <input type="email" id="login-username" name="login-username" autocomplete="username">
  </div>
  <div>
    <label for="login-password" class="form-label">Password</label>
    <input type="password" id="login-password" name="login-password" autocomplete="current-password">
  </div>
  <div>
    <label for="login-totp" class="form-label">2FA code</label>
    <input type="text" id="login-totp" name="login-totp" placeholder="000000" inputmode="numeric" autocomplete="one-time-code">
  </div>
  <input type="submit" value="Submit">
</form>

Please note that testing this code can be quite difficult, you need a password manager with auto-fill for the TOTP field, and you need to convince it that this is a login form. You should see this code as an example only.

I can get my password manager, I am currently using Proton Pass, to auto-fill the user name and password, but not the TOTP field. I've tried to find documentation for developers, for any password manager. I've split the form into 2 separate pages. I even resorted to asking Bing Copilot. Obviously nothing helped.

From all the research I did it seems that password managers only perform auto-fill of the TOTP field for websites that are often used, and they don't tell us, as developers, what they expect of us.

Do you know the secret sauce to get password managers to recognize and auto-fill a TOTP field? Or perhaps this is a fool's errand?

UPDATE 4 May:

I contacted Proton Pass and they answered:

Please note that you can check out the open source code on the link below:

https://github.com/protonpass

Hope this helps, should you have any further questions feel free to reach out to us.

I had already checked out their GitHub, but couldn't make much sense of the stuff there. I think they know that...

UPDATE 11 May:

I reacted to the above answer from Proton Pass and received this reply:

Please note your request was forwarded to the appropriate team. We will reply to your inquiry as soon as possible.

So there's a tiny bit of hope after all. I'll update this question if I know more.


Solution

  • Update 17 May:

    Proton got back to me with the following answer:


    Please note that our development team advised, for web:

    1. Make sure the input is of type "text", "tel" or "number".

    2. Add attributes for pass to get the hints (otp, totp, onetimecode etc.. ie:

    • autocomplete="one-time-code"
    • id="totp"
    • name="totp"
    1. Add a label to your input with some appropriate content without any words that we could detect as an MFA outliers (sms, email, telephone verification codes etc..).

    IE, this will always get detected:

    <div>
      <label for="totp">OTP Code</label>
      <input id="totp" autocomplete="one-time-code" required="" type="text" name="totp">
    </div>
    

    At first this didn't help me, but after a lot of experimenting I came to these conclusions:

    • The input control needs to be inside a <form> tag for the TOTP popup to appear.
    • They look at any word inside the form, to see if it implies another function of the form. In my case I used the word "email" in two places in the form, which stopped the popup from appearing.

    Here's a more detailed explanation. My form looked like this:

    enter image description here

    with the exact code for the input that was advice by Proton, and the input was placed inside a form tag, but still no popup would appear. The popup would only appear after I removed the text line beneath the input field. The code of that line was:

    <div class="col-10">
      <div class="vertical-center">
        <div class="middle-column">
          <div>
            <small>
              <span>No mobile phone?</span>
              <a href="#" id="authenticatemail">Authenticate by email here</a>
            </small>
          </div>
        </div>
      </div>
    </div>
    

    Note that the word "email" occurs twice in this code. Both had to be removed for the popup to work. The form now looks like:

    enter image description here

    And the popup does appear. I haven't tested any other password managers... this took far more effort than I expected. I thought that giving the input field the autocomplete="one-time-code" attribute would be sufficient. It clearly wasn't.

    Similar problems exist when you don't want the popup to appear. The form where people first have to enter a TOTP code to verify their QR-code scan always shows the popup, no matter what I try. Adding the word "email" anywhere in the form turns the input field into an email field, and shows the Proton dropdown for that. Not what I want. I haven't found a good solution for this yet.