Skip to content

Commit b3c61b7

Browse files
author
Daniel Rubery
committed
Minor phrasing and linking updates
1 parent 4c7634f commit b3c61b7

File tree

1 file changed

+70
-68
lines changed

1 file changed

+70
-68
lines changed

spec.bs

+70-68
Original file line numberDiff line numberDiff line change
@@ -72,10 +72,10 @@ different situations. Some of the use cases of DBSC are:
7272

7373
### Signed in session ### {#example-signin}
7474
<div class="example" id="signin-example">
75-
A user logs in to his social account. To protect the user's private data the
76-
site protects his logged in session with a DBSC session. If the user tries to
77-
log in with the same cookie file on a different device, the site can detect and
78-
refuse this as an unauthorized user.
75+
A user logs in to their social account. To protect the user's private data the
76+
site protects the logged in session with a DBSC session. If malware tries to
77+
log in with the same cookie file on a different device, the site can detect
78+
and refuse this as an unauthorized user.
7979
</div>
8080

8181
### Device integrity ### {#example-device-integrity}
@@ -175,7 +175,7 @@ Relying Parties (RPs) could simply establish a DBSC session independently of the
175175
Identity Provider (IdP). Unfortunately, most IdPs do not require a password if
176176
the user is already logged in. Without user interaction, malware can use its
177177
temporary access to the user's machine to mimic the login flow and establish a
178-
DBSC session with a new private key the malware creates and can exfiltrate. This
178+
DBSC session with a new private key the malware created and can exfiltrate. This
179179
violates the security goals of DBSC.
180180

181181
Therefore, we need to link the RP and IdP session in some way. The simplest way
@@ -185,13 +185,13 @@ device, we trust that the private key is stored securely. But sharing keys acros
185185
sites has complex privacy properties. In order to mitigate the privacy risks of
186186
sharing a high-entropy identifier, we require that the RP already know the
187187
public key and session identifier for the IdP's session. The RP will include the
188-
IdP origin, session id, and key in the `Secure-Session-Registration` header. If
188+
IdP origin, session id, and key in the [:Secure-Session-Registration:] header. If
189189
the key is correct, the user agent will create a session on the RP with the same
190190
key as the IdP.
191191

192192
There is a potential risk that malicious RP and IdPs could unmask users by
193193
simply guessing many public keys. This would allow a collaborating RP and IdP to
194-
share a user's identity across sites, outside of the intended mechaisms for
194+
share a user's identity across sites, outside of the intended mechanisms for
195195
cross-site identity leaking. To prevent this, user agents should include
196196
significant backoff or quotas on registration attempts (this is also recommended
197197
to avoid denial of service on the TPM). Note that the security properties of
@@ -200,15 +200,15 @@ the same key pair, so querying whether a user has a specific DBSC public key on
200200
the IdP is much less than a one bit of entropy.
201201

202202
In order to further limit the value of successfully unmasking a user, we also
203-
require opt-in from the IdP through a .well-known. This will ensure that large
203+
require opt-in from the IdP through a `.well-known`. This will ensure that large
204204
groups of sites cannot collaborate to unmask a single high-value user as they
205205
browse the web.
206206

207207
<div class="example" id="federated-sessions-example">
208208
Suppose the owners of `example.com` also run `example.co.uk`. Login always
209209
happens on `example.com`, and is propagated to `example.co.uk` through link
210210
decoration. In order to protect both sites with a DBSC session, `example.com`
211-
should continue to use its existing `Secure-Session-Registration` header:
211+
should continue to use its existing [:Secure-Session-Registration:] header:
212212

213213
```
214214
Secure-Session-Registration: (ES256);path="/register";challenge="challenge"
@@ -227,6 +227,7 @@ on `example.com`. This allows DBSC to protect `example.co.uk` without requiring
227227
users to reauthenticate on `example.com` at login. </div>
228228

229229
# Alternatives considered # {#alternatives}
230+
230231
## WebAuthn and silent mediation ## {#alternatives-webauthn}
231232

232233
# Server considerations # {#server-considerations}
@@ -235,7 +236,7 @@ In order to use DBSC, site owners need to establish two new endpoints:
235236
the registration endpoint and the refresh endpoint.
236237

237238
The registration endpoint is contacted asynchronously after the browser receives
238-
the Secure-Session-Registration header. This endpoint should:
239+
the [:Secure-Session-Registration:] header. This endpoint should:
239240
- Serve the session config, including a new session id.
240241
- Persist and associate the request's public key with the session id.
241242

@@ -246,21 +247,21 @@ cause browser agents to begin denial-of-service prevention mechanisms, or even
246247
terminate the session. Both could lead to future requests without bound
247248
cookies. The expected behavior of this endpoint is:
248249
- Look up the public key and recent challenges for the session by id.
249-
- Validate the Secure-Session-Response header has signed a recent challenge with
250+
- Validate the [:Secure-Session-Response:] header has signed a recent challenge with
250251
the correct key. Note that due to network latency and race conditions, it's
251252
possible to receive a signature for an old challenge after issuing a new
252253
challenge.
253254
- Issue new bound cookies.
254-
- Serve the current session config.
255+
- Optionally update the current session config.
255256

256257
The refresh endpoint is likely to directly leak login state if cross-site
257-
fetches are allowed. Servers can check for a valid Sec-Secure-Session-Id header
258-
to ensure that incoming requests are initiated by the user agent and not a
259-
cross-site request. It's also recommended to set a narrow CORS policy on this
260-
endpoint, not allowing cross-site origins to make requests with credentials. The
261-
CORS integration has been designed to make this possible by implicitly including
262-
credentials when the deferred request does. For similar reasons, it's also
263-
recommended that the refresh endpoint refuse to be embedded via the
258+
fetches are allowed. Servers can check for a valid [:Sec-Secure-Session-Id:]
259+
header to ensure that incoming requests are initiated by the user agent and not
260+
a cross-site request. It's also recommended to set a narrow CORS policy on this
261+
endpoint and not allow cross-site origins to make requests with credentials. The
262+
CORS integration for DBSC has been designed to make this possible by implicitly
263+
including credentials when the deferred request does. For similar reasons, it's
264+
also recommended that the refresh endpoint refuse to be embedded via the
264265
`X-Frame-Options` or `Cross-Origin-Resource-Policy` headers.
265266

266267
<div class="example" id="timing-leak-cors">
@@ -296,8 +297,9 @@ This document depends on the Infra Standard for a number of foundational
296297
concepts used in its algorithms and prose [[!INFRA]].
297298

298299
## Session store ## {#framework-session-store}
299-
The user agent maintains a <dfn>session store</dfn>. It is an
300-
[=ordered map=] from [=host/registrable domain=] to [=session by id=].
300+
The user agent maintains a <dfn>session store</dfn>. It is an [=ordered map=]
301+
from [=host/registrable domain=] to [=session by id=]. Sessions should persist
302+
across user agent restarts.
301303

302304
## Sessions by id ## {#framework-sessions-id}
303305
A <dfn>session by id</dfn> is an [=ordered map=] from
@@ -317,17 +319,17 @@ A <dfn>device bound session</dfn> is a [=struct=] with the following
317319
: <dfn>cached challenge</dfn>
318320
:: a [=string=] that is to be used as the next challenge for this session
319321
: <dfn>session scope</dfn>
320-
:: a [=/session scope=] defining which [=URL=]s are in scope for this session
322+
:: a [=/session scope=] defining which [=URLs=] are in scope for this session
321323
: <dfn>session credentials</dfn>
322-
:: a [=list=] of [=session credential=]s used by the session, derived from
323-
[=/session credentials=]
324+
:: a [=list=] of [=/session credentials=] used by the session, derived from
325+
[=JSON session credentials=]
324326
: <dfn>expiration timestamp</dfn>
325327
:: a [=moment=] when this session should be removed.
326328
: <dfn>session key</dfn>
327329
:: a key pair used by the session. The private key
328330
should be stored in a secure manner, see [[#security-considerations]].
329331
: <dfn>allowed refresh initiators</dfn>
330-
:: a [=list=] of [=string=]s describing which hosts are allowed to initiate
332+
:: a [=list=] of [=strings=] describing which hosts are allowed to initiate
331333
DBSC refreshes due to non-CORS requests. See
332334
[[#algo-request-allows-refresh]] for details.
333335
</dl>
@@ -341,7 +343,7 @@ The <dfn>session scope</dfn> is a [=struct=] with the following
341343
: <dfn>include site</dfn>
342344
:: a [=boolean=] indicating if the session applies to an entire site or just an origin.
343345
: <dfn>scope specifications</dfn>
344-
:: a [=list=] of [=scope specification=]s used by the session
346+
:: a [=list=] of [=/scope specifications=] used by the session
345347
</dl>
346348

347349
## Scope specification ## {#framework-scope-specification}
@@ -454,10 +456,10 @@ if both `co.uk` and `de` are [=public suffixes=].
454456

455457
<div class="example" id="host-pattern-matches-example">
456458
Some examples of pattern matches:
457-
- `https://example.com` matches `*`
458-
- `https://example.com` matches `example.com`
459-
- `https://example.com` does not match `*.example.com`
460-
- `https://subdomain.example.com` matches `*.example.com`
459+
- `example.com` matches `*`
460+
- `example.com` matches `example.com`
461+
- `example.com` does not match `*.example.com`
462+
- `subdomain.example.com` matches `*.example.com`
461463
</div>
462464

463465
</div>
@@ -495,7 +497,7 @@ if both `co.uk` and `de` are [=public suffixes=].
495497

496498
## Identify missing session credential ## {#algo-identify-missing-session-credential}
497499
<div class="algorithm" data-algorithm="identify-missing-session-credential">
498-
Given a [=request=] (|request|) and a [=/list=] of [=/session credential=]s
500+
Given a [=request=] (|request|) and a [=/list=] of [=/session credentials=]
499501
(|credentials|), returns a [=boolean=] indicating whether any |credential| in
500502
|credentials| is missing on |request|.
501503

@@ -776,8 +778,8 @@ id="add-debug-header">add the debug header</dfn> to a [=request=]
776778

777779
# DBSC Formats # {#format}
778780
## \``Secure-Session-Registration`\` HTTP header field ## {#header-secure-session-registration}
779-
The \`<dfn export http-header id="secure-session-registration-header">
780-
<code>Secure-Session-Registration</code></dfn>\` header field can be used in a
781+
The <dfn export http-header id="secure-session-registration-header">
782+
<code>\`Secure-Session-Registration\`</code></dfn> header field can be used in a
781783
[=response=] by the server to start a new [=/device bound session=] on the
782784
client.
783785

@@ -841,8 +843,8 @@ The following <a>sf-parameter</a>s are defined:
841843
</div>
842844

843845
## \``Secure-Session-Challenge`\` HTTP Header Field ## {#header-secure-session-challenge}
844-
The \`<dfn export http-header id="secure-session-challenge-header">
845-
<code>Secure-Session-Challenge</code></dfn>\` header field can be used in a
846+
The <dfn export http-header id="secure-session-challenge-header">
847+
<code>\`Secure-Session-Challenge\`</code></dfn> header field can be used in a
846848
[=response=] by the server to send a challenge to the client that it expects to
847849
be used in future Secure-Session-Response headers inside the [=DBSC proof=], or to
848850
request a newly signed [=DBSC proof=] right away if the [=response/status=]
@@ -855,7 +857,7 @@ The semantics of the item are defined in
855857

856858
The processing steps are defined in [[#algo-process-challenge]].
857859

858-
### Secure-Session-Challenge structured header serialization ### {#challenge-structured-header-serialization}
860+
### [:Secure-Session-Challenge:] structured header serialization ### {#challenge-structured-header-serialization}
859861
The [:Secure-Session-Challenge:] is represented as a Structured Field.[[!RFC9651]]
860862

861863
In this representation, a challenge is represented by a string.
@@ -895,13 +897,13 @@ case the session ID is optional.
895897
```
896898
</div>
897899

898-
## `Secure-Session-Response` HTTP Header Field ## {#header-secure-session-response}
899-
The \`<dfn export http-header id="secure-session-response-header">
900-
<code>Secure-Session-Response</code></dfn>\` header field can be used in the
900+
## \``Secure-Session-Response`\` HTTP Header Field ## {#header-secure-session-response}
901+
The <dfn export http-header id="secure-session-response-header">
902+
<code>\`Secure-Session-Response\`</code></dfn> header field can be used in the
901903
[=request=] by the user agent to send a [=DBSC proof=] to the server to prove
902904
that the client is still in possession of the private key of the session key.
903905

904-
\`<a http-header><code>Secure-Session-Response</code></a>\` is a structured
906+
<a http-header><code>\`Secure-Session-Response\`</code></a> is a structured
905907
header. Its value must be a string. It's ABNF is:
906908
<pre class="abnf">SecSessionChallenge = <a>sf-string</a></pre>
907909
This string MUST only contain the [=DBSC proof=] JWT. Any <a>sf-parameter</a>s SHOULD be
@@ -914,13 +916,13 @@ ignored.
914916
```
915917
</div>
916918

917-
## `Sec-Secure-Session-Id` HTTP Header Field ## {#header-sec-secure-session-id}
918-
The \`<dfn export http-header id="sec-secure-session-id-header">
919-
<code>Sec-Secure-Session-Id</code></dfn>\` header field can be used in the
919+
## \``Sec-Secure-Session-Id`\` HTTP Header Field ## {#header-sec-secure-session-id}
920+
The <dfn export http-header id="sec-secure-session-id-header">
921+
<code>\`Sec-Secure-Session-Id\`</code></dfn> header field can be used in the
920922
[=request=] by the user agent to request the current session is refreshed,
921923
with the current session identifier as a string argument.
922924

923-
\`<a http-header><code>Sec-Secure-Session-Id</code></a>\` is a structured header.
925+
[:Sec-Secure-Session-Id:] is a structured header.
924926
Its value must be a string. It's ABNF is:
925927
<pre class="abnf">SecSessionIdentifier = <a>sf-string</a></pre>
926928
This string MUST only contain the session identifier. Any parameters SHOULD be
@@ -933,9 +935,9 @@ ignored.
933935
```
934936
</div>
935937

936-
## `Secure-Session-Skipped` HTTP header field ## {#header-secure-session-skipped}
937-
The \`<dfn export http-header id="secure-session-skipped-header">
938-
<code>Secure-Session-Skipped</code></dfn>\` header field can be used in a
938+
## \``Secure-Session-Skipped`\` HTTP header field ## {#header-secure-session-skipped}
939+
The <dfn export http-header id="secure-session-skipped-header">
940+
<code>\`Secure-Session-Skipped\`</code></dfn> header field can be used in a
939941
[=request=] to indicate that the request is intentionally missing bound
940942
credentials due to user agent policy.
941943

@@ -960,18 +962,18 @@ One <a>sf-parameter</a> is defined:
960962
</div>
961963

962964

963-
## DBSC Session Instruction Format ## {#format-session-instructions}
964-
The server sends <dfn>session instructions</dfn> during session
965+
## JSON Session Instruction Format ## {#format-session-instructions}
966+
The server sends <dfn>JSON session instructions</dfn> during session
965967
registration and optionally during session refresh. If the response
966968
contains session instructions, it MUST be in JSON format.
967969

968970
At the root of the JSON object, the following keys can exist:
969971
: session identifier
970972
:: a [=string=] representing a [=device bound session/session identifier=].
971-
If this [=session instructions=] is sent during a refresh request this MUST be
973+
If this [=JSON session instructions=] is sent during a refresh request this MUST be
972974
the [=device bound session/session identifier=] for the current session. If
973975
not these instructions SHOULD be ignored.
974-
If this [=session instructions=] is sent during a registration it MUST either
976+
If this [=JSON session instructions=] is sent during a registration it MUST either
975977
be a unique identifier for this [=host/registrable domain=], or it will
976978
overwrite the current [=device bound session=] with this identifier for the
977979
current [=host/registrable domain=].
@@ -989,15 +991,15 @@ At the root of the JSON object, the following keys can exist:
989991
This key is OPTIONAL, and if not present, the default value will be true.
990992

991993
: scope
992-
:: a [=dictionary=] of [=session scope instructions=] describing the request
993-
destinations covered by the session. This field MUST be present.
994+
:: a [=JSON session scope=] describing the request destinations covered by
995+
the session. This field MUST be present.
994996

995997
: credentials
996-
:: a [=list=] of [=/session credentials=] describing the cookies protected by
998+
:: a [=list=] of [=JSON session credentials=] describing the cookies protected by
997999
this session. This field MUST be present.
9981000

9991001
: allowed_refresh_initiators
1000-
:: a [=list=] of [=string=]s describing which hosts are allowed to initiate
1002+
:: a [=list=] of [=strings=] describing which hosts are allowed to initiate
10011003
DBSC refreshes due to non-CORS requests. See
10021004
[[#algo-request-allows-refresh]] for details.
10031005

@@ -1041,8 +1043,8 @@ At the root of the JSON object, the following keys can exist:
10411043
```
10421044
</div>
10431045

1044-
## DBSC Session Scope Instruction Format ## {#format-session-scope-instructions}
1045-
The server sends <dfn>session scope instructions</dfn> in the [=session
1046+
## JSON Session Scope Instruction Format ## {#format-session-scope-instructions}
1047+
The server sends a <dfn>JSON session scope</dfn> in the [=JSON session
10461048
instructions=] during registration and optionally during session refresh.
10471049

10481050
At the root of the JSON object, the following keys can exist:
@@ -1056,19 +1058,19 @@ At the root of the JSON object, the following keys can exist:
10561058
:: a [=boolean=] indicating if the session is origin-scoped (false) or
10571059
site-scoped (true). This key is OPTIONAL; if not present, it will be false
10581060
(origin-scoped). Note that this takes precedence over any
1059-
[=session scope rule=]s in [=scope specification=] (see
1061+
[=JSON session scope rules=] in [=scope specification=] (see
10601062
[[#algo-url-in-scope]]).
10611063

10621064
: scope_specification
1063-
:: a [=list=] of [=session scope rule=]s describing modifications to the
1065+
:: a [=list=] of [=JSON session scope rules=] describing modifications to the
10641066
default scope (the entire origin or site). This key is OPTIONAL; if not
10651067
present, an empty list will be used.
10661068

1067-
## DBSC Session Scope Rule Format ## {#format-session-scope-rule}
1068-
The server sends <dfn>session scope rule</dfn>s in the [=session scope
1069-
instructions=] during registration and optionally during session refresh.
1069+
## JSON Session Scope Rule Format ## {#format-session-scope-rule}
1070+
The server sends <dfn>JSON session scope rules</dfn> in the [=JSON session scope=]
1071+
during registration and optionally during session refresh.
10701072

1071-
At the root of each [=session scope rule=], the following keys can exist:
1073+
At the root of each [=JSON session scope rule=], the following keys can exist:
10721074
: type
10731075
:: a [=string=] indicating whether the rule includes or excludes destinations.
10741076
This key MUST be present, and the value MUST be "include" or "exclude".
@@ -1081,8 +1083,8 @@ At the root of each [=session scope rule=], the following keys can exist:
10811083
:: a [=string=] indicating the path-prefixes that should match the rule. This
10821084
key MUST be present. See [[#algo-url-in-scope]] for the detailed semantics.
10831085

1084-
## DBSC Session Credentials Format ## {#format-session-credentials}
1085-
The server sends <dfn>session credentials</dfn> in the [=session
1086+
## JSON Session Credentials Format ## {#format-session-credentials}
1087+
The server sends <dfn>JSON session credentials</dfn> in the [=JSON session
10861088
instructions=] during registration and optionally during session refresh.
10871089

10881090
At the root of the JSON object, the following keys can exist:
@@ -1173,11 +1175,11 @@ present:
11731175

11741176
This specification requires an update to the <a
11751177
href="https://fetch.spec.whatwg.org/#http-network-or-cache-fetch">HTTP-network-or-cache
1176-
fetch</a> algorithm. A [=request=] has a <dfn
1177-
for="request">deferred device bound session ids</dfn>, a [=list=] of [=tuple=]s consisting of:
1178+
fetch</a> algorithm. A [=request=] has a <dfn for="request">deferred device
1179+
bound session ids</dfn>, a [=list=] of [=tuples=] consisting of:
11781180
- a domain (a [=host/registrable domain=]).
11791181
- a session id (a [=string=]).
1180-
This list is initially empty. At the end of step 8.21, run
1182+
This list is initially empty. After computing cookies in step 8.21, run
11811183
[[#algo-identify-session-needing-refresh]]. If the resulting
11821184
|session| is non-null:
11831185
1. Run [[#algo-session-request]] with the returned |session|'s

0 commit comments

Comments
 (0)