Origin-bound one-time codes delivered via SMS

Draft Community Group Report,

This version:
https://wicg.github.io/sms-one-time-codes/
Issue Tracking:
GitHub
Editors:
(Apple)
(Google)

Abstract

This specification defines a way to format SMS messages for use with browser autofill features such as HTML’s autocomplete=one-time-code.

Status of this document

This specification was published by the Web Platform Incubator Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

Introduction

This section is non-normative.

Many websites deliver one-time codes over SMS. [GSM-SMS]

Without a standard format for such messages, programmatic extraction of codes from them has to rely on heuristics, which are often unreliable and error-prone. Additionally, without a mechanism for associating such codes with specific websites, users might be tricked into providing the code to malicious sites.

This specification defines a format for the delivery of one-time codes over SMS. This format associates the one-time code with a specific website.

1. Infrastructure

This specification depends on the Infra Standard. [INFRA]

2. Origin-bound one-time codes

An origin-bound one-time code is a tuple consisting of a top-level origin (an origin), an embedded origin (an origin or null), and a code (a string).

(("https", "example.com", null, null), null, "747723") is an origin-bound one-time code whose top-level origin is ("https", "example.com", null, null), whose embedded origin is null, and whose code is "747723".

(("https", "example.com", null, null), ("https", "ecommerce.example", null, null), "747723") is an origin-bound one-time code whose origin is ("https", "example.com", null, null), whose embedded origin is ("https", "ecommerce.example", null, null), and whose code is "747723".

2.1. Usage

Many User Agents help users fill out forms on websites. Sites can use features like autocomplete=one-time-code to hint to User Agents that they could assist the user with providing a one-time code to the website. [HTML]

Note: This specification does not impose any requirements or restrictions on the use of one-time codes which are not origin-bound one-time codes.

User Agents determine whether or not to assist the user to provide an origin-bound one-time code to a website with origin-bound one-time code otc and Document doc by running these steps:

  1. If doc is not the active document of a browsing context, return failure.

  2. Let context be doc’s browsing context.

  3. If context is a top-level browsing context. run these steps:

    1. If otc’s embedded origin is not null, return failure.

    2. If otc’s top-level origin is same origin with doc’s origin, return "origin".

    3. If otc’s top-level origin is same site with doc’s origin, return "site".

    4. Return failure.

  4. If otc’s embedded origin is null, return failure.

  5. Let match type be "origin".

  6. If otc’s embedded origin is not same origin with doc’s origin, set match type to "site".

  7. If otc’s embedded origin is not same site with doc’s origin, return failure.

  8. Set context to its parent browsing context.

  9. While context is not a top-level browsing context, run these steps:

    1. If context’s active document's origin is same origin with neither otc’s embedded origin nor otc’s top-level origin, set match type to "site".

    2. If context’s active document's origin is same site with neither otc’s embedded origin nor otc’s top-level origin, return failure.

    3. Set context to its parent browsing context.

  10. If context is not a top-level browsing context, return failure.

  11. If context’s active document's origin is same origin with otc’s top-level origin, return match type.

  12. If context’s active document's origin is same site with otc’s top-level origin, return "site".

  13. Return failure.

If the above steps returned "origin" or "site", the User Agent may assist the user with providing the origin-bound one-time code's code to the website.

If the above steps returned "site", the User Agent should indicate the origin-bound one-time code's top-level and embedded origins to the user when assisting them.

If the above steps returned failure, the User Agent should not assist the user with providing the origin-bound one-time code's code to the website.

Note: because the schemes of an origin-bound one-time code's top-level and embedded origins are always "https", assisting the user with providing origin-bound one-time codes is only available in secure contexts.

3. Message format

An origin-bound one-time code message is a string for which parsing an origin-bound one-time code message successfully returns an origin-bound one-time code.

3.1. Authoring

This section is non-normative. § 3.2 Parsing is the normative text.

Origin-bound one-time code messages can optionally begin with human-readable explanatory text. This consists of all but the last line of the message. The last line of the message contains both a top-level host and a code, each prefixed with a sigil: U+0040 (@) before the top-level host, and U+0023 (#) before the code. Following the code, an embedded host can be specified. It is preceeded with a U+0040 (@) sigil.

In the following origin-bound one-time code message, the top-level host is "example.com", the code is "747723", no embedded host is specified, and the explanatory text is "747723 is your ExampleCo authentication code.\n\n".

"747723 is your ExampleCo authentication code.

@example.com #747723"

In the following origin-bound one-time code message, the top-level host is "example.com", the code is "747723", the embedded host is "ecommerce.example", and the explanatory text is "747723 is your ExampleCo authentication code.\n\n".

"747723 is your ExampleCo authentication code.

@example.com #747723 @ecommerce.example"

The order of fields in the last line is always top-level host, code, and embedded host (if present). Nothing can come before the top-level host in the last line.

The message "something @example.com #747723" is not an origin-bound one-time code message, because it doesn’t start with the top-level host.

The message "#747723 @ecommerce.example @example.com" is not an origin-bound one-time code message, because the fields are in the wrong order.

Exactly one U+0020 (SPACE) separates the values in the last line of the message.

The message "@example.com code #747723" is not an origin-bound one-time code message, because several characters appear between the two values on the last line of the message.

Trailing text in the last line is ignored. This is because we might identify additional information to include in origin-bound one-time code messages in the future. If we do, new syntax could be introduced after the existing syntax in the last line.

In the origin-bound one-time code message "@example.com #747723 @ecommerce.example $future", the top-level host is "example.com", the code is "747723", the embedded host is "ecommerce.example", and the explanatory text is "". The trailing text " %future" is ignored.

3.2. Parsing

To parse an origin-bound one-time code message from message, run these steps:

  1. Let line be the last line of message, and position be 0.

  2. If position points past the end of line, return failure.

  3. Let top-level host be the result of extracting a marked token from line at position with marker U+0040 (@).

  4. If top-level host is failure, return failure.

  5. Let top-level origin be the origin ("https", top-level host, null, null).

  6. If position points past the end of line, return failure.

  7. If the code point at position within line is not U+0020 (SPACE), return failure.

  8. Advance position by 1.

  9. If position points past the end of line, return failure.

  10. Let code be the result of extracting a marked token from line at position with marker U+0023 (#).

  11. If code is failure, return failure.

  12. Let embedded origin be null.

  13. If position does not point past the end of line, and if the code point at position within line is U+0020 (SPACE), run the following steps:

    1. Advance position by 1.

    2. Let embedded host be the result of extracting a marked token from line at position with marker U+0040 (@).

    3. If embedded host is failure, set embedded origin to null. Otherwise, set embedded origin to the origin ("https", embedded host, null, null).

  14. Return the origin-bound one-time code (top-level origin, embedded origin, code).

To extract a marked token from string at position with code point marker, run the following steps:

  1. If position points past the end of string, return failure.

  2. If the code point at position within string is not marker, return failure.

  3. Advance position by 1.

  4. If position points past the end of string, return failure.

  5. Let token be the result of collecting a sequence of code points which are not ASCII whitespace from string with position.

  6. If token is the empty string, return failure.

  7. Return token.

The last line of string is the result of running these steps:

  1. Normalize newlines in string.

  2. Let lines be the result of strictly splitting string on U+000A (LF).

  3. Return the last item of lines.

4. Security considerations

This specification attempts to mitigate the phishing risk associated with the delivery of one-time codes over SMS by enabling User Agents to know what website the one-time code is intended for.

This specification does not attempt to mitigate other risks associated with the delivery of one-time codes over SMS, such as SMS spoofing, SIM swapping, SIM cloning, ISMI-catchers, or interception of the message by an untrusted party.

Sites would do well to consider using non-SMS technologies such as [WEBAUTHN] for authentication or verification.

5. Privacy considerations

Any party which has access to a user’s SMS messages (such as the user’s cellular carrier, mobile operating system, or anyone who intercepted the message) can learn that the user has an account on the service identified in an origin-bound one-time code message delivered over SMS.

On some platforms, User Agents might need access to all incoming SMS messages—even messages which are not origin-bound one-time code messages—in order to support the autofilling of origin-bound one-time codes delivered over SMS in origin-bound one-time code messages.

Acknowledgements

Many thanks to Aaron Parecki, Elaine Knight, Eric Shepherd, Eryn Wells, Jay Mulani, Ricky Mondello, and Steven Soneff for their valuable feedback on this proposal.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119

Informative References

[GSM-SMS]
Richard Burbidge. Technical realization of the Short Message Service (SMS). URL: http://www.3gpp.org/ftp/Specs/html-info/23040.htm
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBAUTHN]
Dirk Balfanz; et al. Web Authentication:An API for accessing Public Key Credentials Level 1. 4 March 2019. REC. URL: https://www.w3.org/TR/webauthn-1/