Dispatch E. Wells Internet-Draft T. O'Connor Intended status: Informational Apple Inc. Expires: 9 June 2024 7 December 2023 Origin-Bound One-Time Codes draft-wells-origin-bound-one-time-codes-00 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. Copyright Notice Copyright (c) 2023 IETF Trust and the persons identified as the document authors. All rights reserved. This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 Wells & O'Connor Expires 9 June 2024 [Page 1] Internet-Draft Origin-Bound One-Time Codes December 2023 1.1. Conventions and Definitions . . . . . . . . . . . . . . . 3 1.1.1. Algorithms . . . . . . . . . . . . . . . . . . . . . 3 1.1.2. Examples and Notes . . . . . . . . . . . . . . . . . 4 2. Origin-Bound One-Time Codes . . . . . . . . . . . . . . . . . 4 3. Message Formats . . . . . . . . . . . . . . . . . . . . . . . 4 3.1. SMS . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 3.1.1. Parsing (SMS) . . . . . . . . . . . . . . . . . . . . 6 3.2. Email . . . . . . . . . . . . . . . . . . . . . . . . . . 8 3.2.1. Parsing (Message Header) . . . . . . . . . . . . . . 9 4. Usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 5. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 11 6. Security Considerations . . . . . . . . . . . . . . . . . . . 12 7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 12 8. Implementation Status . . . . . . . . . . . . . . . . . . . . 12 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 12 9.1. Normative References . . . . . . . . . . . . . . . . . . 12 9.2. Informative References . . . . . . . . . . . . . . . . . 13 Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 13 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 13 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. Wells & O'Connor Expires 9 June 2024 [Page 2] Internet-Draft Origin-Bound One-Time Codes December 2023 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 (https://dom.spec.whatwg.org/#document) and Origin (https://dom.spec.whatwg.org/#concept-document-origin), see [DOM]. For definitions of Active Document (https://html.spec.whatwg.org/multipage/browsers.html#active- document), Browsing Context (https://html.spec.whatwg.org/multipage/ browsers.html#browsing-context), Parent Browsing Context (https://html.spec.whatwg.org/multipage/browsers.html#parent- browsing-context), Same Origin (https://html.spec.whatwg.org/multipage/origin.html#same-origin), Same Site (https://html.spec.whatwg.org/multipage/origin.html#same- site), and Top-Level Context (https://html.spec.whatwg.org/multipage/ document-sequences.html#top-level-browsing-context), see [HTML]. For definitions of ASCII Whitespace (https://infra.spec.whatwg.org/#ascii-whitespace), Code Point (https://infra.spec.whatwg.org/#code-point), Collect a Sequence of Code Points (https://infra.spec.whatwg.org/#collect-a-sequence-of- code-points), Normalize Newlines (https://infra.spec.whatwg.org/#normalize-newlines), Strictly Split (https://infra.spec.whatwg.org/#strictly-split), and Tuple (https://infra.spec.whatwg.org/#tuple), see [INFRA]. 1.1.1. Algorithms Many requirements in this document take the form of precise algorithms as is the norm in WHATWG (https://whatwg.org/) (Web Hypertext Application Technology Working Group) and many W3C (https://www.w3.org/) specifications. These algorithms are expressed per the requirements (https://infra.spec.whatwg.org/#algorithms) 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. Wells & O'Connor Expires 9 June 2024 [Page 3] Internet-Draft Origin-Bound One-Time Codes December 2023 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 (https://infra.spec.whatwg.org/#tuple) consisting of a *top-level origin* (an origin (https://dom.spec.whatwg.org/#concept-document- origin)), an *embedded origin* (an origin (https://dom.spec.whatwg.org/#concept-document-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. Wells & O'Connor Expires 9 June 2024 [Page 4] Internet-Draft Origin-Bound One-Time Codes December 2023 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. Wells & O'Connor Expires 9 June 2024 [Page 5] Internet-Draft Origin-Bound One-Time Codes December 2023 @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://dom.spec.whatwg.org/#concept-document-origin) ("https", _top-level host_, null, null). 6. If _position_ points past the end of _line_, return failure. 7. If the code point (https://infra.spec.whatwg.org/#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 (https://infra.spec.whatwg.org/#code-point) at _position_ within _line_ is U+0020 (SPACE), run the following steps: 1. Advance _position_ by 1. Wells & O'Connor Expires 9 June 2024 [Page 6] Internet-Draft Origin-Bound One-Time Codes December 2023 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://dom.spec.whatwg.org/#concept-document-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 (https://infra.spec.whatwg.org/#code-point) _marker_, run the following steps: 1. If _position_ points past the end of _string_, return failure. 2. If the code point (https://infra.spec.whatwg.org/#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 (https://infra.spec.whatwg.org/#collect-a-sequence-of-code- points) which are not ASCII whitespace (https://infra.spec.whatwg.org/#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 (https://infra.spec.whatwg.org/#normalize- newlines) in _string_. 2. Let _lines_ be the result of strictly splitting (https://infra.spec.whatwg.org/#strictly-split) _string_ on U+000A (LF). Wells & O'Connor Expires 9 June 2024 [Page 7] Internet-Draft Origin-Bound One-Time Codes December 2023 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 Wells & O'Connor Expires 9 June 2024 [Page 8] Internet-Draft Origin-Bound One-Time Codes December 2023 *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 (https://html.spec.whatwg.org/multipage/form-control- infrastructure.html#attr-fe-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 by providing an origin-bound one-time code to a website* with origin-bound one- time code _otc_ and Document (https://dom.spec.whatwg.org/#document) _doc_ by running these steps: 1. If _doc_ is not the active document (https://html.spec.whatwg.org/multipage/browsers.html#active- document) of a browsing context (https://html.spec.whatwg.org/multipage/browsers.html#browsing- context), return failure. 2. Let _context_ be _doc_’s browsing context (https://html.spec.whatwg.org/multipage/browsers.html#browsing- context). 3. If _context_ is a top-level browsing context (https://html.spec.whatwg.org/multipage/document- sequences.html#top-level-browsing-context), run these steps: 1. If _otc_’s embedded origin is not null, return failure. Wells & O'Connor Expires 9 June 2024 [Page 9] Internet-Draft Origin-Bound One-Time Codes December 2023 2. If _otc_’s top-level origin is same origin (https://html.spec.whatwg.org/multipage/origin.html#same- origin) with _doc_’s origin (https://dom.spec.whatwg.org/#concept-document-origin), return "origin". 3. If _otc_’s top-level origin is same site (https://html.spec.whatwg.org/multipage/origin.html#same- site) with _doc_’s origin (https://dom.spec.whatwg.org/#concept-document-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 (https://html.spec.whatwg.org/multipage/origin.html#same-origin) with _doc_’s origin (https://dom.spec.whatwg.org/#concept- document-origin), set _match type_ to "site". 7. If _otc_’s embedded origin is not same site (https://html.spec.whatwg.org/multipage/origin.html#same-site) with _doc_’s origin (https://dom.spec.whatwg.org/#concept- document-origin), return failure. 8. Set _context_ to its parent browsing context (https://html.spec.whatwg.org/multipage/browsers.html#parent- browsing-context). 9. While _context_ is not a top-level browsing context (https://html.spec.whatwg.org/multipage/document- sequences.html#top-level-browsing-context), run these steps: 1. If _context_’s active document's origin (https://dom.spec.whatwg.org/#concept-document-origin) is same origin (https://html.spec.whatwg.org/multipage/ origin.html#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 (https://dom.spec.whatwg.org/#concept-document-origin) is same site (https://html.spec.whatwg.org/multipage/ origin.html#same-site) with neither _otc_’s embedded origin nor _otc_’s top-level origin, return failure. Wells & O'Connor Expires 9 June 2024 [Page 10] Internet-Draft Origin-Bound One-Time Codes December 2023 3. Set _context_ to its parent browsing context (https://html.spec.whatwg.org/multipage/ browsers.html#parent-browsing-context). 10. If _context_ is not a top-level browsing context (https://html.spec.whatwg.org/multipage/document- sequences.html#top-level-browsing-context), return failure. 11. If _context_'s active document (https://html.spec.whatwg.org/multipage/browsers.html#active- document)'s origin (https://dom.spec.whatwg.org/#concept- document-origin) is same origin (https://html.spec.whatwg.org/multipage/origin.html#same-origin) with _otc_'s top-level origin, return _match type_. 12. If _context_’s active document's origin (https://dom.spec.whatwg.org/#concept-document-origin) is same site (https://html.spec.whatwg.org/multipage/origin.html#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 (https://www.iana.org/assignments/message-headers/message- headers.xhtml): Header field name: One-Time-Code Wells & O'Connor Expires 9 June 2024 [Page 11] Internet-Draft Origin-Bound One-Time Codes December 2023 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 Wells & O'Connor Expires 9 June 2024 [Page 12] Internet-Draft Origin-Bound One-Time Codes December 2023 [BCP90] Klyne, G., Nottingham, M., and J. Mogul, "Registration Procedures for Message Header Fields", BCP 90, RFC 3864, September 2004. [DOM] "DOM", W3C REC dom, W3C dom, . [HTML] "HTML", W3C REC html, W3C html, . [INFRA] van Kesteren, A. and D. Denicola, "Infra Standard", 27 June 2023, . Living Standard. [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC6376] Crocker, D., Ed., Hansen, T., Ed., and M. Kucherawy, Ed., "DomainKeys Identified Mail (DKIM) Signatures", STD 76, RFC 6376, DOI 10.17487/RFC6376, September 2011, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . 9.2. Informative References [SMS] 3GPP and N. M. Amin, "Technical realization of the Short Message Service (SMS)", 6 June 2008, . [WEBAUTHN] "Web Authentication:An API for accessing Public Key Credentials Level 1", W3C REC webauthn-1, W3C 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 Wells & O'Connor Expires 9 June 2024 [Page 13] Internet-Draft Origin-Bound One-Time Codes December 2023 Eryn Wells Apple Inc. Email: eryn_wells@apple.com Theresa O'Connor Apple Inc. Email: hober@apple.com Wells & O'Connor Expires 9 June 2024 [Page 14]