Html: Add `one-time-code` autocomplete field

Created on 6 Jun 2018  Â·  14Comments  Â·  Source: whatwg/html

Sites often require users to demonstrate their identity by providing a one-time-code that is sent to the user out-of-band. For example, the site may email the user's email address on file, or send and SMS to the user's known phone number.

Manually typing such codes into sites is cumbersome and error-prone. We propose the addition of a one-time-code autocomplete field name to help UAs automatically fill such fields to improve this.

Field name | Meaning | Canonical Format | Canonical Format Example | Control group
-------- | -------- | -------- | -------- | --------
"one-time-code" | One-time code used for verifying user identity | Free-form text, no newlines | 123456 | Password

additioproposal forms

All 14 comments

This is implemented in Safari 12 on macOS 10.14 and iOS 12.

I'm a little unclear how strictly we should apply the implementer interest criteria for autofill field standardization. But hopefully we can get multi-implementer interest and not have to even worry about it...

@mnoorenberghe thoughts for Firefox? I guess the main reason we don't have this in HTML right now is because 2FA came after this was initially standardized?

I saw this the other day on developer.apple.com and thought it made sense to add to HTML. We've had bugs filed before to not save these fields in form history or in password manager because they aren't going to be useful so one-time-code could aid in solving that… The risk in using it for that purpose is that it will be (ab)used on regular password fields to prevent saving/filling non-one-time-use passwords. Some of those same concerns already apply to new-password, though ideally in that case a browser password generation UI could discourage abuse… I'm not sure how we could discourage that type of abuse for this value yet.

Overall I think the addition makes sense, especially where a password manager will help to fill the field, rather than just avoid filling something else (e.g. the user's regular password for that origin), I just worry it will be abused by websites that try to work against password managers… hopefully that will end one day. +1 from me

The risk in using it for that purpose is that it will be (ab)used on regular password fields to prevent saving/filling non-one-time-use passwords.

People do this with the autocomplete="off" (docs) attribute already, albeit browsers have begun to ignore this.

Hey folks!

I think adding one-time-code as an autocomplete attribute is reasonable. I can imagine password managers that support TOTP making good use of it, for instance. For that kind of use case, it seem pretty reasonable. I'm a bit more skeptical about the SMS use case cross-platform. For example, on platforms like Android each browser would need to grab SMS permissions and scan through incoming messages to autofill the field, which we'd like to avoid doing.

Android offers an lower-privilege SMS Retriever API that we're interested in exploring, however: https://developers.google.com/identity/sms-retriever/overview. That's a platform-level API that waits for incoming messages that meet a certain template, and passes just those messages on to the relevant application. That is, the platform would give Chrome a short hash, we'd lengthen it to include origin-level routing information, and give the developer an SMS template string, perhaps something like:

<#>
%s

---
random-token-that-identifies-the-origin-and-renderer
token-that-identifies-the-Chrome-app

The developer could use the Credential Management API to grab a Promise that would resolve when the SMS came in, and send the codes gathered back up to the server for verification.

We'd sketched out an API along the lines of:

// On Android, |smsTemplate| would contain something like "<#>\n%s\n[tokens and stuff]".
// Presumably other platforms would have their own variants based on the underlying
// platform API (iOS might hand over `Code: %s`, for instance).
let smsTemplate = SmsCredential.getMessageTemplate();

navigator.credentials.get({ "sms": true }).then(c => {
  // This promise will resolve when an SMS matching |smsTemplate| is received and routed
  // to the browser by the underlying platform.

  // `SmsCredential.text()` returns the body of the SMS message, stripped of any required
  // prefix and suffix (e.g. `<#>` and the one-time-token on Android).
  let text = c.text();

  // The application can now verify the message by POSTing something to the server.
  let init = { method: "POST", body: text, credentials: "include" };
  fetch("https://same-origin.example/verify-sms/", init)
      .then(r => {
          // If |r| is valid, do cool, validated things. If not, don't.
      });
});

// Once the handler is set up, tell the server to send the user a message (presumably
// the server knows the user's phone number...)
let init = { method: "POST", body: smsTemplate, credentials: "include" };
fetch("https://same-origin.example/send-sms", init);

Would y'all interested in exploring that kind of lower-privilege, imperative approach? I think it has some security advantages that I find pretty interesting.

Right, I was involved in ignoring it in Firefox and contributed to those docs. My point was that I don’t
want to have to ignore ‘one-time-code’ too down the road (after
implementation) due to abuse.

On Thu, Jun 7, 2018 at 12:19 AM Thomas Steiner notifications@github.com
wrote:

The risk in using it for that purpose is that it will be (ab)used on
regular password fields to prevent saving/filling non-one-time-use
passwords.

People do this with the autocomplete="off" (docs
https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion)
attribute already, albeit browsers have begun to ignore this.

I added the needs implementer interest keyword, though perhaps @mnoorenberghe's "+1 from me" is sufficient to pass the multi-implementor-interest bar.

FWIW I almost added some support for this in Firefox a few months ago but hesitated since it wasn't in the spec yet. We will likely only use it for the following in the foreseeable future:
a) Don't save the value in form history
b) Don't autofill passwords into it (we will still allow the user to fill a saved password with user interaction to mitigate potential abuse that I mentioned earlier)

That definitely sounds like implementor interest, then. :) Removing the keyword.

Sounds like we should add this to the spec! Although I think it's a little weird that it sounds like Firefox's plan for implementing is to just treat it as autocomplete=off?

But as I briefly noted up thread, autofill is a weird area, so as long as we have multiple browsers who want to consider this field special in some way, we should land something in the spec that the ecosystem can coordinate around.

Okay, I have the spec change & WPT update mostly prepped locally. I'll submit a PR soon.

@hober, if I'm a website author, your specification doesn't tell me enough to know how I should send an SMS that'll actually autofill on the user's platform. Do I need to user-agent-sniff to get the right format on iOS vs Android? Is @mikewest right that browsers on Android can't auto-fill this at all?

@jyasskin it'd probably be best to track that separately at this point, given this was merged.

Was this page helpful?
0 / 5 - 0 ratings