Internet-Draft Origin-Bound One-Time Codes December 2023
Wells & O'Connor Expires 9 June 2024 [Page]
Workgroup:
Dispatch
Internet-Draft:
draft-wells-origin-bound-one-time-codes-00
Published:
Intended Status:
Informational
Expires:
Authors:
E. Wells
Apple Inc.
T. O'Connor
Apple Inc.

Origin-Bound One-Time Codes

Abstract

This specification defines a mechanism for associating one-time codes with domains that can be included in the body of an SMS message or the headers of an email.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 9 June 2024.

Table of Contents

1. Introduction

Many websites use one-time codes to provide an additional layer of security when users log in with passwords. These one-time codes can be delivered over a variety of transports, but [SMS] and email are the most common.

To improve the experience of dealing with these codes, User Agents might attempt to automatically extract them and present them to the user for filling. Without a well-defined format for such messages, extraction relies on heuristics, which are often unreliable and error-prone. Additionally, without a mechanism for associating such codes with specific domains, users might be tricked into providing the code to a malicious site.

This document defines a mechanism for associating one-time codes with origins, and formats for specifying them in SMS messages and emails. The benefits of this association are that senders of one-time codes can specify to User Agents which domains the one-time code is valid for, and User Agents can reliably extract one-time codes from these messages without relying on heuristics.

1.1. Conventions and Definitions

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

For definitions of Document and Origin, see [DOM].

For definitions of Active Document, Browsing Context, Parent Browsing Context, Same Origin, Same Site, and Top-Level Context, see [HTML].

For definitions of ASCII Whitespace, Code Point, Collect a Sequence of Code Points, Normalize Newlines, Strictly Split, and Tuple, see [INFRA].

1.1.1. Algorithms

Many requirements in this document take the form of precise algorithms as is the norm in WHATWG (Web Hypertext Application Technology Working Group) and many W3C specifications. These algorithms are expressed per the requirements in [INFRA].

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.

1.1.2. Examples and Notes

Examples are marked at the start of the paragraph in bold with a letter.

Example Z. This is the 26th example in this document.

Notes are marked at the start of the paragraph in bold.

Note: This is an informative note.

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).

Example A. (("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".

Example B. (("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".

3. Message Formats

3.1. SMS

An origin-bound one-time code SMS is a string for which the "parse an origin-bound one-time code SMS" algorithm (Section 3.1.1) returns an origin-bound one-time code.

An origin-bound one-time code SMS MAY begin with human-readable explanatory text. This consists of all but the last line of the string.

The last line MUST contain 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 MAY be specified. It is preceeded with a U+0040 (@) sigil.

The fields on the last line MUST be separated by a single U+0020 (SPACE). 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.

Trailing text in the last line SHOULD be ignored to preserve the ability for future documents to introduce new syntax.

Example C. In the following origin-bound one-time code SMS, 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

Example D. In the following origin-bound one-time code SMS, 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".

747723 is your ExampleCo authentication code.
@example.com #747723 @ecommerce.example

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

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

Example G. 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.

Example H. In the following origin-bound one-time code SMS, 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.

@example.com #747723 @ecommerce.example $future

3.1.1. Parsing (SMS)

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

  1. Let line be the last line (Section 3.1.1.2) 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 (Section 3.1.1.1) 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 (Section 3.1.1.1) 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 (Section 3.1.1.1) 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).

3.1.1.1. Extracting a Marked Token

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.

3.1.1.2. Extracting the Last Line of a String

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.

3.2. Email

In order to deliver an origin-bound one-time code via email, we define a One-Time-Code message header that contains the one-time code and origin-binding information about it.

The information in the body of this header MUST use a DKIM-style tag list as defined in Section 3.2 of [RFC6376]. The following tag names are defined:

origin

The top-level origin the code is bound to

code

The code itself

embedded-origin

The embedded origin

The header body MUST contain exactly one code tag. It SHOULD include one origin tag. If the header body contains an origin tag, it MAY also include one embedded-origin tag.

Though it is recommended to always provide origin-binding information along with one-time codes, senders can affirmatively decline to provide it, while still including the code to assist User Agents with detecting it, by omitting the origin and embedded-origin tags. MUAs MAY choose to ignore the One-Time-Code header if an origin tag is not specified.

Example I. The following header specifies an origin-bound one-time code where the code is "123456" and the origin is "example.com".

One-Time-Code: code=123456; origin=example.com

Example J. The following example is an origin-bound one-time code header with an origin of "example.com", a code of "123456", and an embedded domain of "ecommerce.example"

One-Time-Code: origin=example.com; code=123456;
               embedded-origin=ecommerce.example.com

Example K. The following example is not a domain-bound one-time code header because it is missing an origin tag.

One-Time-Code: code=123456;
               embedded-origin=ecommerce.example.com

Example L. The following header specifies a code, but does not specify origin-binding information. Therefore, it is not an origin-bound one-time code.

One-Time-Code: code=123456

3.2.1. Parsing (Message Header)

Parsing the body of the One-Time-Code header proceeds according to [RFC6376].

4. Usage

Many User Agents help users fill out forms on websites. Sites can use features like autocomplete=one-time-code (defined in HTML) 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 by providing 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.

5. IANA Considerations

Per [BCP90], the following provisional message header field will be submitted to the IANA Message Headers registry:

Header field name:

One-Time-Code

Applicable protocol:

mail

Status:

provisional

Author/Change controller:

TBD (the working group that takes this up)

Specification document(s):

This document.

Related information:

None.

6. Security Considerations

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

This document does not attempt to mitigate other risks associated with the delivery of one-time codes over SMS or email. Interception of messages by untrusted parties, and account cloning and takeover attacks are still possible even with domain-binding information.

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

7. Privacy Considerations

Any party which has access to a user’s SMS or email 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 these transport mechanisms.

On some platforms, User Agents might need access to all incoming SMS and email 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 or email in origin-bound one-time code messages.

8. Implementation Status

Apple and Google ship implementations of the domain-bound one-time code parser for SMS messages.

9. References

9.1. Normative References

[BCP90]
Klyne, G., Nottingham, M., and J. Mogul, "Registration Procedures for Message Header Fields", BCP 90, RFC 3864, .
[DOM]
"DOM", W3C REC dom, W3C dom, <https://www.w3.org/TR/dom/>.
[HTML]
"HTML", W3C REC html, W3C html, <https://www.w3.org/TR/html/>.
[INFRA]
van Kesteren, A. and D. Denicola, "Infra Standard", , <https://infra.spec.whatwg.org/>. Living Standard.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC6376]
Crocker, D., Ed., Hansen, T., Ed., and M. Kucherawy, Ed., "DomainKeys Identified Mail (DKIM) Signatures", STD 76, RFC 6376, DOI 10.17487/RFC6376, , <https://www.rfc-editor.org/rfc/rfc6376>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, , <https://www.rfc-editor.org/rfc/rfc8174>.

9.2. Informative References

[SMS]
3GPP and N. M. Amin, "Technical realization of the Short Message Service (SMS)", , <http://www.3gpp.org/ftp/Specs/archive/23_series/23.040/23040-3b0.zip>.
[WEBAUTHN]
"Web Authentication:An API for accessing Public Key Credentials Level 1", W3C REC webauthn-1, W3C webauthn-1, <https://www.w3.org/TR/webauthn-1/>.

Acknowledgments

Many thanks to Aaron Parecki, Arielle Davenport, Ashley Clark, Elaine Knight, Eric Shepherd, Irene Valdes Salazar, Jay Mulani, Phillip Tao, Ricky Mondello, and Steven Soneff for their valuable feedback on this document.

Authors' Addresses

Eryn Wells
Apple Inc.
Theresa O'Connor
Apple Inc.