Skip to content

Commit 31aa41c

Browse files
committed
One possible way to handle nested iframes.
1 parent 22b6cfb commit 31aa41c

File tree

2 files changed

+85
-29
lines changed

2 files changed

+85
-29
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,21 @@ In this example,
6969

7070
The characters `"@"` and `"#"` identify the origin and the code, respectively. (We can always introduce additional prefix characters in the future if it turns out we need to include additional information in these messages.)
7171

72+
Some sites use third-party `iframe`s for authentication. In such cases, the third-party `iframe`'s origin can be specified using a `"%"` field after the code.
73+
74+
```text
75+
747723 is your ExampleCo authentication code.
76+
77+
@example.com #747723 %ecommerce.example
78+
```
79+
80+
In this example,
81+
82+
* `"https://example.com"` is the origin the code is associated with,
83+
* `"747723"` is the code,
84+
* `"https://ecommerce.example"` is the origin of the third-party `iframe`, and
85+
* `"747723 is your ExampleCo authentication code.\n\n"` is human-readable explanatory text.
86+
7287
## Benefits
7388

7489
Adoption of this format would improve the reliability of systems which today heuristically extract one-time codes from SMS, with clear end-user benefit. It improves reliability of both extracting the code and also associating that code with an origin.

index.bs

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ Editor: Sam Goto, Google https://google.com, goto@google.com
1111
Abstract: This specification defines a way to format SMS messages for use with browser autofill features such as HTML's autocomplete=one-time-code.
1212
Markup Shorthands: markdown yes, css no
1313
Complain About: accidental-2119 true
14+
Remove Multiple Links: yes
1415
</pre>
1516

1617
<pre class="link-defaults">
1718
spec:infra; type:dfn; text:size; for:list
1819
spec:infra; type:dfn; text:string
19-
spec:url; type:dfn; text:origin
2020
spec:url; type:dfn; text:scheme
2121
</pre>
2222

@@ -30,7 +30,7 @@ Many websites deliver one-time codes over SMS. [[GSM-SMS]]
3030

3131
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.
3232

33-
This specification defines a format for the delivery of one-time codes over SMS. This format associates the one-time code with a specific [=origin=].
33+
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.
3434

3535
</div>
3636

@@ -40,31 +40,45 @@ This specification depends on the Infra Standard. [[!INFRA]]
4040

4141
<h2 id="origin-bound-one-time-codes">Origin-bound one-time codes</h2>
4242

43-
An <dfn export>origin-bound one-time code</dfn> is a [=tuple=] consisting of an [=origin=] and a code (a [=string=]).
43+
An <dfn export>origin-bound one-time code</dfn> is a [=tuple=] consisting of a top-level origin (an [=/origin=]), an embedded origin (an [=/origin=] or `null`), and a code (a [=string=]).
4444

4545
<div class=example>
4646

47-
((`"https"`, `"example.com"`, `null`, `null`), `"747723"`) is an [=origin-bound one-time code=] whose origin is (`"https"`, `"example.com"`, `null`, `null`) and whose code is `"747723"`.
47+
((`"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"`.
4848

4949
</div>
5050

51-
<h3 id="usage">Usage</h3>
51+
<div class=example>
5252

53-
Many User Agents help users fill out forms on websites. Sites can use features like <a href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete-one-time-code">`autocomplete=one-time-code`</a> to hint to User Agents that they could assist the user with providing a one-time code to the website. [[HTML]]
53+
((`"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"`.
5454

55-
<!-- We should be able to reference autocomplete=one-time-code with Bikeshed syntax along the lines of <{html/autocomplete/one-time-code}>. See whatwg/html#5418. -->
55+
</div>
5656

57-
In this section, an <dfn>active origin</dfn> is an [=origin=] of a [=top-level browsing context=]'s [=active document=].
57+
<h3 id="usage">Usage</h3>
5858

59-
When a User Agent is in possession of an [=origin-bound one-time code=] and an [=active origin=] is <strong>[=same origin=]</strong> with the [=origin-bound one-time code=]'s origin, the User Agent may assist the user with providing the [=origin-bound one-time code=]'s code to the website.
59+
Many User Agents help users fill out forms on websites. Sites can use features like <a href="https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fe-autocomplete-one-time-code">`autocomplete=one-time-code`</a> to hint to User Agents that they could assist the user with providing a one-time code to the website. [[HTML]]
6060

61-
When a User Agent is in possession of an [=origin-bound one-time code=] and an [=active origin=] is <strong>[=same site=] but not [=same origin=]</strong> with the [=origin-bound one-time code=]'s origin, the User Agent may assist the user with providing the [=origin-bound one-time code=]'s code to the website, and should indicate the [=origin-bound one-time code=]'s origin to the user.
61+
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=].
6262

63-
When a User Agent is in possession of an [=origin-bound one-time code=] and an [=active origin=] is <strong>neither [=same site=] nor [=same origin=]</strong> with the [=origin-bound one-time code=]'s origin, the User Agent should not assist the user with providing the [=origin-bound one-time code=]'s code to the website.
63+
<!-- We should be able to reference autocomplete=one-time-code with Bikeshed syntax along the lines of <{html/autocomplete/one-time-code}>. See whatwg/html#5418. -->
6464

65-
Note: because the [=scheme=] of an [=origin-bound one-time code=]'s origin is always `"https"`, assisting the user with providing [=origin-bound one-time codes=] is only available in [=secure contexts=].
65+
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:
6666

67-
This specification does not impose any requirements or restrictions on the use of one-time codes which are not [=origin-bound one-time codes=].
67+
1. If |doc| is not the [=active document=] of a [=/browsing context=], return failure.
68+
1. Let |context| be |doc|'s [=Document/browsing context=].
69+
1. If |context| is a [=top-level browsing context=]. run these steps:
70+
1. If |otc|'s embedded origin is not `null`, return failure.
71+
1. If |otc|'s top-level origin is [=same site=] with |doc|'s [=Document/origin=], return success. Otherwise, return failure.
72+
1. If |otc|'s embedded origin is `null`, return failure.
73+
1. If |otc|'s embedded origin is not [=same site=] with |doc|'s [=Document/origin=], return failure.
74+
1. Set |context| to its [=parent browsing context=].
75+
1. While |context| is not a [=top-level browsing context=], run these steps:
76+
1. If |context|'s [=active document=]'s [=Document/origin=] is neither [=same site=] with |otc|'s embedded origin nor |otc|'s top-level origin, return failure.
77+
1. Set |context| to its [=parent browsing context=].
78+
1. If |context| is not a [=top-level browsing context=], return failure.
79+
1. If |context|'s [=active document=]'s [=Document/origin=] is [=same site=] with |otc|'s top-level origin, return success. Otherwise, return failure.
80+
81+
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=].
6882

6983
<h2 id="format">Message format</h2>
7084

@@ -77,11 +91,11 @@ An <dfn export>origin-bound one-time code message</dfn> is a [=string=] for whic
7791

7892
<em>This section is non-normative. [[#parsing]] is the normative text.</em>
7993

80-
[=Origin-bound one-time code messages=] can optionally begin with human-readable <dfn for="origin-bound one-time code message">explanatory text</dfn>. This consists of all but the last line of the message. The last line of the message contains both a <dfn for="origin-bound one-time code message">host</dfn> and a <dfn for="origin-bound one-time code message">code</dfn>, each prefixed with a sigil: U+0040 (@) before the <a for="origin-bound one-time code message">host</a>, and U+0023 (#) before the [=code=].
94+
[=Origin-bound one-time code messages=] can optionally begin with human-readable <dfn for="origin-bound one-time code message">explanatory text</dfn>. This consists of all but the last line of the message. The last line of the message contains both a <dfn for="origin-bound one-time code message">top-level host</dfn> and a <dfn for="origin-bound one-time code message">code</dfn>, each prefixed with a sigil: U+0040 (@) before the [=origin-bound one-time code message/top-level host=], and U+0023 (#) before the [=code=]. Following the [=code=], an <dfn for="origin-bound one-time code message">embedded host</dfn> can be specified. It is preceeded with a U+0025 (%) sigil.
8195

8296
<div class="example">
8397

84-
In the following [=origin-bound one-time code message=], the <a for="origin-bound one-time code message">host</a> is `"example.com"`, the [=code=] is `"747723"`, and the [=explanatory text=] is `"747723 is your ExampleCo authentication code.\n\n"`.
98+
In the following [=origin-bound one-time code message=], the [=origin-bound one-time code message/top-level host=] is `"example.com"`, the [=code=] is `"747723"`, no [=origin-bound one-time code message/embedded host=] is specified, and the [=explanatory text=] is `"747723 is your ExampleCo authentication code.\n\n"`.
8599

86100
```
87101
"747723 is your ExampleCo authentication code.
@@ -91,21 +105,33 @@ In the following [=origin-bound one-time code message=], the <a for="origin-boun
91105

92106
</div>
93107

94-
The last line has to begin with U+0040 (@). (Which is to say, the <a for="origin-bound one-time code message">host</a> always comes before the [=code=] in the message.)
108+
<div class="example">
109+
110+
In the following [=origin-bound one-time code message=], the [=origin-bound one-time code message/top-level host=] is `"example.com"`, the [=code=] is `"747723"`, the [=origin-bound one-time code message/embedded host=] is `"ecommerce.example"`, and the [=explanatory text=] is `"747723 is your ExampleCo authentication code.\n\n"`.
111+
112+
```
113+
"747723 is your ExampleCo authentication code.
114+
115+
@example.com #747723 %ecommerce.example"
116+
```
117+
118+
</div>
119+
120+
The order of fields in the last line is always [=origin-bound one-time code message/top-level host=], [=code=], and [=origin-bound one-time code message/embedded host=] (if present). Nothing can come before the [=origin-bound one-time code message/top-level host=] in the last line.
95121

96122
<div class="example">
97123

98-
The message `"something @example.com #747723"` is not an [=origin-bound one-time code message=], because its last line does not begin with U+0040 (@).
124+
The message `"something @example.com #747723"` is not an [=origin-bound one-time code message=], because it doesn't start with the [=origin-bound one-time code message/top-level host=].
99125

100126
</div>
101127

102128
<div class="example">
103129

104-
The message `"#747723 @example.com"` is not an [=origin-bound one-time code message=], because its last line does not begin with U+0040 (@).
130+
The message `"#747723 %ecommerce.example @example.com"` is not an [=origin-bound one-time code message=], because the fields are in the wrong order.
105131

106132
</div>
107133

108-
Exactly one U+0020 (SPACE) separates the two values in the last line of the message.
134+
Exactly one U+0020 (SPACE) separates the values in the last line of the message.
109135

110136
<div class="example">
111137

@@ -117,7 +143,7 @@ Trailing text in the last line is ignored. This is because we might identify add
117143

118144
<div class="example">
119145

120-
In the [=origin-bound one-time code message=] `"@example.com #747723 %future"`, the <a for="origin-bound one-time code message">host</a> is `"example.com"`, the [=code=] is `"747723"`, and the [=explanatory text=] is `""`. The trailing text `" %future"` is ignored.
146+
In the [=origin-bound one-time code message=] `"@example.com #747723 %ecommerce.example $future"`, the [=origin-bound one-time code message/top-level host=] is `"example.com"`, the [=code=] is `"747723"`, the [=origin-bound one-time code message/embedded host=] is `"ecommerce.example"`, and the [=explanatory text=] is `""`. The trailing text `" $future"` is ignored.
121147

122148
</div>
123149

@@ -128,17 +154,32 @@ In the [=origin-bound one-time code message=] `"@example.com #747723 %future"`,
128154
To <dfn export type="abstract-op">parse an origin-bound one-time code message</dfn> from |message|, run these steps:
129155

130156
1. Let |line| be the [=last line=] of |message|, and |position| be 0.
131-
1. If the code point at |position| within |line| is not U+0040 (@), return failure.
132-
1. Advance |position| by 1.
133-
1. Let |host| be the result of [=collecting a sequence of code points=] which are not [=ASCII whitespace=] from |line| with |position|.
134-
1. If |host| is the empty string, return failure.
135-
1. If the code point at |position| within |line| is not U+0020 (SPACE), return failure.
157+
1. If |position| points past the end of |line|, return failure.
158+
1. Let |top-level host| be the result of [=extract a marked token|extracting a marked token=] from |line| at |position| with marker U+0040 (@).
159+
1. If |top-level host| is failure, return failure.
160+
1. Let |top-level origin| be the [=/origin=] (`"https"`, |top-level host|, `null`, `null`).
161+
1. If |position| points past the end of |line|, return failure.
162+
1. If the [=code point=] at |position| within |line| is not U+0020 (SPACE), return failure.
136163
1. Advance |position| by 1.
137-
1. If the code point at |position| within |line| is not U+0023 (#), return failure.
164+
1. If |position| points past the end of |line|, return failure.
165+
1. Let |code| be the result of [=extract a marked token|extracting a marked token=] from |line| at |position| with marker U+0023 (#).
166+
1. If |code| is failure, return failure.
167+
1. Let |embedded origin| be null.
168+
1. 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:
169+
1. Advance |position| by 1.
170+
1. Let |embedded host| be the result of [=extract a marked token|extracting a marked token=] from |line| at |position| with marker U+0025 (%).
171+
1. If |embedded host| is failure, set |embedded origin| to null. Otherwise, set |embedded origin| to the [=/origin=] (`"https"`, |embedded host|, `null`, `null`).
172+
1. Return the [=origin-bound one-time code=] (|top-level origin|, |embedded origin|, |code|).
173+
174+
To <dfn type="abstract-op">extract a marked token</dfn> from |string| at |position| with [=code point=] |marker|, run the following steps:
175+
176+
1. If |position| points past the end of |string|, return failure.
177+
1. If the [=code point=] at |position| within |string| is not |marker|, return failure.
138178
1. Advance |position| by 1.
139-
1. Let |code| be the result of [=collecting a sequence of code points=] which are not [=ASCII whitespace=] from |line| with |position|.
140-
1. If |code| is the empty string, return failure.
141-
1. Return the [=origin-bound one-time code=] ((`"https"`, |host|, `null`, `null`), |code|).
179+
1. If |position| points past the end of |string|, return failure.
180+
1. Let |token| be the result of [=collecting a sequence of code points=] which are not [=ASCII whitespace=] from |string| with |position|.
181+
1. If |token| is the empty string, return failure.
182+
1. Return |token|.
142183

143184
The <dfn type=abstract-op>last line</dfn> of |string| is the result of running these steps:
144185

0 commit comments

Comments
 (0)