Re: [whatwg/fetch] Update Fetch to support Token Binding. (#325)

annevk commented on this pull request.

Overall this still looks like a very complex addition to the platform that I don't feel fully equipped to judge.

I'm particularly concerned with adding more state to connections and how that will interact with HTTP/2 connection coalescing and the existing separation of connection pools.

It's also concerning we violate the same-origin policy here yet again, but I guess that's just the level-playing field for any kind of authentication scheme these days.

> @@ -966,6 +984,40 @@ for other values. If <cite>HTML</cite> changes here, this standard will need cor
 Unless stated otherwise, it is unset.
 
 <p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-use-token-binding>use-token-binding flag</dfn>.
+Unless stated otherwise, it is unset.
+
+<p class="note no-backref"><a for=/>Request</a>'s <a for=request>use-token-binding flag</a>
+controls whether the user agent will send the <a for=/>token binding ID</a> for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url when it transmits the
+<a for=/>request</a> to the server. The <a for=/>token binding ID</a> can be used by the server to,
+e.g., bind credentials that it issues to the user agent.

Is this https://fetch.spec.whatwg.org/#credentials or something more specific?

> +Unless stated otherwise, it is unset.
+
+<p class="note no-backref"><a for=request>Request</a>'s
+<a for=request>use-referred-token-binding flag</a> controls whether the user agent will send the
+<a for=/>token binding ID</a> used by the user agent for an alternate <a for=request>origin</a>,
+in addition to the <a for=/>token binding ID</a> used by the user agent for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url, when it transmits the
+<a for=/>request</a> to the server. This is used, e.g., by a relying party to indicate
+(via the user agent) to the server receiving the <a for=/>request</a> that it wants the
+credential issued by the server to be bound to the <a for=/>token binding ID</a> for the
+relying party's <a for=request>origin</a>
+(instead of the <a for=/>request</a>'s <a for=request>origin</a>).
+
+<p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-referred-token-binding-origin>referred-token-binding-origin</dfn>,
+which is an <a for=request>origin</a>. Unless stated otherwise, it is null.

I suspect this should be `<a for=/>origin</a>`, no?

> +e.g., bind credentials that it issues to the user agent.
+
+<p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-use-referred-token-binding>use-referred-token-binding flag</dfn>.
+Unless stated otherwise, it is unset.
+
+<p class="note no-backref"><a for=request>Request</a>'s
+<a for=request>use-referred-token-binding flag</a> controls whether the user agent will send the
+<a for=/>token binding ID</a> used by the user agent for an alternate <a for=request>origin</a>,
+in addition to the <a for=/>token binding ID</a> used by the user agent for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url, when it transmits the
+<a for=/>request</a> to the server. This is used, e.g., by a relying party to indicate
+(via the user agent) to the server receiving the <a for=/>request</a> that it wants the
+credential issued by the server to be bound to the <a for=/>token binding ID</a> for the
+relying party's <a for=request>origin</a>
+(instead of the <a for=/>request</a>'s <a for=request>origin</a>).

So this is when a request goes from A to B and B redirects to C, right? What if this is not set and B redirects? Does that result in an error?

> +<a for=/>token binding ID</a> used by the user agent for an alternate <a for=request>origin</a>,
+in addition to the <a for=/>token binding ID</a> used by the user agent for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url, when it transmits the
+<a for=/>request</a> to the server. This is used, e.g., by a relying party to indicate
+(via the user agent) to the server receiving the <a for=/>request</a> that it wants the
+credential issued by the server to be bound to the <a for=/>token binding ID</a> for the
+relying party's <a for=request>origin</a>
+(instead of the <a for=/>request</a>'s <a for=request>origin</a>).
+
+<p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-referred-token-binding-origin>referred-token-binding-origin</dfn>,
+which is an <a for=request>origin</a>. Unless stated otherwise, it is null.
+
+<p class="note no-backref"><a for=/>Request</a>'s
+<a for=request>referred-token-binding-origin</a>
+specifies the <a for=request>origin</a> used to determine the <a for=/>referred token Binding ID</a>,

this also seems like the wrong origin.

> +<a for=/>token binding ID</a> used by the user agent for an alternate <a for=request>origin</a>,
+in addition to the <a for=/>token binding ID</a> used by the user agent for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url, when it transmits the
+<a for=/>request</a> to the server. This is used, e.g., by a relying party to indicate
+(via the user agent) to the server receiving the <a for=/>request</a> that it wants the
+credential issued by the server to be bound to the <a for=/>token binding ID</a> for the
+relying party's <a for=request>origin</a>
+(instead of the <a for=/>request</a>'s <a for=request>origin</a>).
+
+<p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-referred-token-binding-origin>referred-token-binding-origin</dfn>,
+which is an <a for=request>origin</a>. Unless stated otherwise, it is null.
+
+<p class="note no-backref"><a for=/>Request</a>'s
+<a for=request>referred-token-binding-origin</a>
+specifies the <a for=request>origin</a> used to determine the <a for=/>referred token Binding ID</a>,

Also, this should probably be "referred-token-binding ID"?

> +<dfn export for=request id=concept-request-use-referred-token-binding>use-referred-token-binding flag</dfn>.
+Unless stated otherwise, it is unset.
+
+<p class="note no-backref"><a for=request>Request</a>'s
+<a for=request>use-referred-token-binding flag</a> controls whether the user agent will send the
+<a for=/>token binding ID</a> used by the user agent for an alternate <a for=request>origin</a>,
+in addition to the <a for=/>token binding ID</a> used by the user agent for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url, when it transmits the
+<a for=/>request</a> to the server. This is used, e.g., by a relying party to indicate
+(via the user agent) to the server receiving the <a for=/>request</a> that it wants the
+credential issued by the server to be bound to the <a for=/>token binding ID</a> for the
+relying party's <a for=request>origin</a>
+(instead of the <a for=/>request</a>'s <a for=request>origin</a>).
+
+<p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-referred-token-binding-origin>referred-token-binding-origin</dfn>,

This should probably be "referred-token-binding origin" (no hyphen at the end).

> +  highest supported <a for=/>Token Binding</a> protocol version and supported cryptographic
+  algorithms and parameters (the
+  <dfn export id=concept-token-binding-key-parameters>token binding key parameters</dfn>) in a
+  <code>token_binding</code> Client Hello Extension, as described in
+  <a href="https://tools.ietf.org/html/draft-ietf-tokbind-negotiation#section-2">section 2</a>
+  of the Token Binding Negotiation spec [[!TOKBIND-NEGOTIATION]].
+  If Token Binding Negotiation succeeds, indicating client-server agreement on protocol version
+  and <a for=/>token binding key parameters</a>, update metadata for the TLS connection with the
+  results of the negotiation.
+
+  <p class="note no-backref">
+  The user agent will use <a for=/>Token Binding</a> for any <a for=/>request</a> sent over
+  a TLS connection for which Token Binding Negotiation was successful.
+  Since <a for=/>Token Binding</a> is used only when <var>credentials</var> is true, such a
+  connection will not be pooled with connections that have <var>credentials</var> is
+  false.

How does this work if I do another `fetch()` where I opt out of token binding but still use cookies? In that case I shouldn't be able to reuse the connection that has token binding, right?

> @@ -966,6 +984,40 @@ for other values. If <cite>HTML</cite> changes here, this standard will need cor
 Unless stated otherwise, it is unset.
 
 <p>A <a for=/>request</a> has an associated
+<dfn export for=request id=concept-request-use-token-binding>use-token-binding flag</dfn>.
+Unless stated otherwise, it is unset.
+
+<p class="note no-backref"><a for=/>Request</a>'s <a for=request>use-token-binding flag</a>
+controls whether the user agent will send the <a for=/>token binding ID</a> for the
+<a for=request>origin</a> of the <a for=/>request</a>'s url when it transmits the
+<a for=/>request</a> to the server. The <a for=/>token binding ID</a> can be used by the server to,
+e.g., bind credentials that it issues to the user agent.

It seems to be something more specific and not necessarily credentials that are kept by the user agent (e.g., OAuth is not kept by the user agent).

> @@ -2172,6 +2243,201 @@ exploits pertain to those <a for=request>types</a>. Also, considering "<code>ima
 compatible with deployed content.
 
 
+<h3 id=token-binding>Token Binding</h3>
+
+<p>In order to protect security tokens like cookies and OAuth tokens, user agents and servers can

HTTP cookies*

> @@ -2172,6 +2243,201 @@ exploits pertain to those <a for=request>types</a>. Also, considering "<code>ima
 compatible with deployed content.
 
 
+<h3 id=token-binding>Token Binding</h3>
+
+<p>In order to protect security tokens like cookies and OAuth tokens, user agents and servers can
+use a technique known as <dfn export id=concept-token-binding>Token Binding</dfn> to
+cryptographically associate a given token with a secret
+(a <dfn export id=concept-token-binding-key>token binding key</dfn>) known only to a specific

token-binding key* (per other names)

> @@ -2172,6 +2243,201 @@ exploits pertain to those <a for=request>types</a>. Also, considering "<code>ima
 compatible with deployed content.
 
 
+<h3 id=token-binding>Token Binding</h3>
+
+<p>In order to protect security tokens like cookies and OAuth tokens, user agents and servers can
+use a technique known as <dfn export id=concept-token-binding>Token Binding</dfn> to
+cryptographically associate a given token with a secret
+(a <dfn export id=concept-token-binding-key>token binding key</dfn>) known only to a specific
+user agent. This association mitigates the risk that attackers can steal the token and use it
+themselves, as they will not be able to easily replicate the user agent's secret,
+and therefore cannot replicate the cryptographic binding of the token.
+
+<p>The technique is described in
+detail in [[TOKBIND-NEGOTIATION]], [[TOKBIND-PROTOCOL]], and [[TOKBIND-HTTPS]].

I think this should be better as "Details are described in X, Y, and Z, and integration is defined here. [[X]] [[Y]] [[Z]]".

> +detail in [[TOKBIND-NEGOTIATION]], [[TOKBIND-PROTOCOL]], and [[TOKBIND-HTTPS]].
+
+<p>A <dfn export id=token-binding-id>token binding ID</dfn> is the representation
+of a <a for=/>token binding</a>, as described in
+<a href="https://tools.ietf.org/html/draft-ietf-tokbind-protocol#section-3.2">section 3.2</a>
+of [[TOKBIND-PROTOCOL]].
+
+<p>At a very high level, a user agent negotiates the use of Token Binding with the server when it
+sets up a TLS connection to the server, and saves metadata (the Token Binding protocol version and <a for=/>token binding key parameters</a> resulting from the Token Binding negotiation) for the
+TLS connection. The user agent maintains a <a for=/>token binding key</a> store, where it saves
+different <a for=/>token binding key</a>s to be used with different servers. Whenever the
+<a for=/>token binding key</a> is needed, the user agent looks it up in the
+<a for=/>token binding key</a> store (creating it if needed).
+When the user agent sends a <a for=/>request</a> to the server over the TLS connection,
+it proves possession of the private key by adding and signing a <a for=/>token binding ID</a> in a
+Token Binding HTTP <a for=/>header</a>. The server associates ('binds') credentials that it

Better to name that header name here directly I think.

> +Sec-Token-Binding       = 1*( ALPHA / DIGIT / "-" / "_" ) *2( "=" )
+</pre>
+
+<p>The value of the <code>Sec-Token-Binding</code> <a for=/>header</a> is a
+<dfn export id=token-binding-message>Token Binding Message</dfn> as specified in
+<a href="https://tools.ietf.org/html/draft-ietf-tokbind-https#section-2">section 2</a>
+of the Token Binding over HTTP spec [[!TOKBIND-HTTPS]].
+A <a for=/>token binding message</a> is a list of <a for=/>token binding</a>s,
+where each <a for=/>token binding</a> consists of a
+<a for=/>token binding ID</a>, a <a for=/>token binding type</a> and a cryptographic signature.
+
+<h4 id=federated-token-binding>Federated Token Binding</h4>
+
+<p>In the scenario described above, servers bind tokens to be used by user agents
+with those servers.
+To enable existing Web Authorization protocols to use bound credentials,

This is capitalized in a way that feels like it needs a reference, but maybe it should just be lowercased?

> +where each <a for=/>token binding</a> consists of a
+<a for=/>token binding ID</a>, a <a for=/>token binding type</a> and a cryptographic signature.
+
+<h4 id=federated-token-binding>Federated Token Binding</h4>
+
+<p>In the scenario described above, servers bind tokens to be used by user agents
+with those servers.
+To enable existing Web Authorization protocols to use bound credentials,
+there is a need to support scenarios where bound credentials issued by one server
+(e.g., an identity provider) are presented by the user agent to a different server
+(e.g., a relying party).
+[[TOKBIND-PROTOCOL]] and [[TOKBIND-HTTPS]] describe support for Federated Token Binding.
+
+<p>A <dfn export id=referred-token-binding-id>referred token binding ID</dfn> is the
+<a for=/>token binding ID</a> for a server other than the server to which the <a for=/>request</a>
+is being sent.

What if these servers use the same connection through HTTP/2 connection coalescing?

> +(e.g., an identity provider) are presented by the user agent to a different server
+(e.g., a relying party).
+[[TOKBIND-PROTOCOL]] and [[TOKBIND-HTTPS]] describe support for Federated Token Binding.
+
+<p>A <dfn export id=referred-token-binding-id>referred token binding ID</dfn> is the
+<a for=/>token binding ID</a> for a server other than the server to which the <a for=/>request</a>
+is being sent.
+
+Script code from an <a for=/>origin</a> can set a <a for=/>request</a>'s
+<a for=request>use-referred-token-binding flag</a> to ask the user agent to send
+the <a for=/>token binding ID</a> for that <a for=/>origin</a> as a
+<a for=/>referred token binding ID</a>
+in the <a for=/>Token Binding Message</a> sent to a target server.
+
+Alternately, servers that redirect a user agent to a different server can use the
+<code>Include-Referred-Token-Binding-ID</code> <a for=response>header</a>.

We use backticks for header names (since they're effectively byte sequences).

> +the <a for=/>token binding ID</a> for that <a for=/>origin</a> as a
+<a for=/>referred token binding ID</a>
+in the <a for=/>Token Binding Message</a> sent to a target server.
+
+Alternately, servers that redirect a user agent to a different server can use the
+<code>Include-Referred-Token-Binding-ID</code> <a for=response>header</a>.
+
+<pre>
+Include-Referred-Token-Binding-ID = %x74.72.75.65 ; "true", case-sensitive
+</pre>
+
+<p>The value of this <a for=response>header</a> is specified in
+<a href="https://tools.ietf.org/html/draft-ietf-tokbind-https#section-5.3">section 5.3</a>
+of the Token Binding over HTTP spec [[TOKBIND-HTTPS]].
+
+By setting the <code>Include-Referred-Token-Binding-ID</code> <a for=response>header</a> to

Please use `<p>`

> +<a for=/>referred token binding ID</a>
+in the <a for=/>Token Binding Message</a> sent to a target server.
+
+Alternately, servers that redirect a user agent to a different server can use the
+<code>Include-Referred-Token-Binding-ID</code> <a for=response>header</a>.
+
+<pre>
+Include-Referred-Token-Binding-ID = %x74.72.75.65 ; "true", case-sensitive
+</pre>
+
+<p>The value of this <a for=response>header</a> is specified in
+<a href="https://tools.ietf.org/html/draft-ietf-tokbind-https#section-5.3">section 5.3</a>
+of the Token Binding over HTTP spec [[TOKBIND-HTTPS]].
+
+By setting the <code>Include-Referred-Token-Binding-ID</code> <a for=response>header</a> to
+"<code>true</code>" in the redirect response, the <a for=request>origin</a> of the server that

Use
```
`<code>true</code>`
```
for header values (which are also byte sequences).

> +<a for=/>Token Binding</a> sense) tells the user agent to disclose the
+<a for=/>token binding ID</a> used by the user agent for that <a for=request>origin</a>
+to the target <a for=request>origin</a>. The user agent does this while processing the
+<code>Include-Referred-Token-Binding-ID</code> header in the redirect <a for=/>response</a>
+by adding a <a for=/>referred token binding ID</a> in the <a for=/>Token Binding Message</a>
+used when the <a for=/>request</a> is sent to the target server.
+
+<h4 id=getting-token-binding-key>Getting a Token Binding Key</h4>
+
+<p>Get the <a for=/>token binding key</a> for an <a for=/>origin</a> <var>tokenBindingOrigin</var>
+and <a for=/>token binding key parameters</a> <var>tokenBindingKeyParameters</var>,
+using the user agent's <a for=/>token binding key</a> store, by running these substeps:
+
+<ol>
+ <li><p>Let <var>publicNameSuffix</var> be the public name suffix - the Effective Top-Level
+ Domain + 1 name (eTLD + 1) of <var>tokenBindingOrigin</var>'s host.

This needs to be a lot more formal. HTML has something similar, but this seems slightly different: https://html.spec.whatwg.org/multipage/browsers.html#is-a-registrable-domain-suffix-of-or-is-equal-to.

It seems the above would result in an error of sorts if the host was an IP address. You should account for that.

> +
+<h4 id=getting-token-binding-key>Getting a Token Binding Key</h4>
+
+<p>Get the <a for=/>token binding key</a> for an <a for=/>origin</a> <var>tokenBindingOrigin</var>
+and <a for=/>token binding key parameters</a> <var>tokenBindingKeyParameters</var>,
+using the user agent's <a for=/>token binding key</a> store, by running these substeps:
+
+<ol>
+ <li><p>Let <var>publicNameSuffix</var> be the public name suffix - the Effective Top-Level
+ Domain + 1 name (eTLD + 1) of <var>tokenBindingOrigin</var>'s host.
+
+ <li><p>Get <var>tokenBindingKeyPair</var>, the <a for=/>token binding key</a> pair for
+ <var>publicNameSuffix</var>, by running these substeps:
+
+ <ol>
+  <li><p>Initialize <var>tokenBindingKeyPair</var> to null.

Variables are used like this:

> Let _X_ be null.
> Set _X_ to ...

> +<code>Include-Referred-Token-Binding-ID</code> header in the redirect <a for=/>response</a>
+by adding a <a for=/>referred token binding ID</a> in the <a for=/>Token Binding Message</a>
+used when the <a for=/>request</a> is sent to the target server.
+
+<h4 id=getting-token-binding-key>Getting a Token Binding Key</h4>
+
+<p>Get the <a for=/>token binding key</a> for an <a for=/>origin</a> <var>tokenBindingOrigin</var>
+and <a for=/>token binding key parameters</a> <var>tokenBindingKeyParameters</var>,
+using the user agent's <a for=/>token binding key</a> store, by running these substeps:
+
+<ol>
+ <li><p>Let <var>publicNameSuffix</var> be the public name suffix - the Effective Top-Level
+ Domain + 1 name (eTLD + 1) of <var>tokenBindingOrigin</var>'s host.
+
+ <li><p>Get <var>tokenBindingKeyPair</var>, the <a for=/>token binding key</a> pair for
+ <var>publicNameSuffix</var>, by running these substeps:

Why do you even need substeps here? Can't you just return directly when you have the value?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/fetch/pull/325#pullrequestreview-28155770

Received on Tuesday, 21 March 2017 16:30:20 UTC