Subject: Re: I-D Action: draft-ietf-httpbis-http2-encryption-07.txt

From: Kari hurtta <[email-masked]>
Date: Tue, 4 Oct 2016 19:03:20 +0300 (EEST)

> There's also a htmlized version available at:
> https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07

2.  Using HTTP URIs over TLS
https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07#section-2

|    An origin server that supports the resolution of "http" URIs can
|    indicate support for this specification by providing an alternative
|    service advertisement [RFC7838] for a protocol identifier that uses
|    TLS, such as "h2" [RFC7540].

This allows also other than "h2" (for example "http/1.1", which
is HTTP/1.1 over TLS).

2.1.  Alternative Server Opt-In
https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07#section-2.1

|    Clients MUST NOT send "http" requests over a connection with the "h2"
|    protocol identifier, unless they have obtained a valid http-
|    opportunistic response for an origin (as per Section 2.3), and:

But this part is specific to "h2".

What part of this specification is valid when prococol
identifier is not "h2" ?

/ Kari Hurtta

---

From: Kari hurtta <[email-masked]>
Date: Tue, 4 Oct 2016 19:41:00 +0300 (EEST)

Also

|   GET /.well-known/http-opportunistic HTTP/1.1
|   Host: www.example.com
|
|   HTTP/1.1 200 OK
|   Content-Type: application/json
|   Connection: close
|
|   {
|     "http://www.example.com": {
|       "tls-ports": [443, 8000],
|       "lifetime": 2592000
|     }
|   }

This seems use HTTP/1.1 over TLS, but on same chapter there was

so there is also mismatch with example.

Also if "http/1.1" protocol identifier is allowed, then
this example really should use absoluteURI and not abs_path.

-----------------------------------------
GET http://www.example.com/.well-known/http-opportunistic HTTP/1.1

HTTP/1.1 200 OK
Content-Type: application/json
Connection: close

{
  "http://www.example.com": {
    "tls-ports": [443, 8000],
    "lifetime": 2592000
  }
}
-----------------------------------------

Scheme is needed on here.

If protocol identifier "http/1.1" is here allowed for 
alternative service advertisement, then there need to 
be requrement for use absoluteURI on HTTP/1.1
requests.

/ Kari Hurtta

---

From: Mike Bishop <[email-masked]>
Date: Tue, 4 Oct 2016 17:38:45 +0000

Building on Kari's feedback below, advertising an alternative with protocol "h2" (or "http/1.1") isn't really an opt-in for this specification.  Such a server could legitimately be implementing RFC 7838 as-is, which does not forbid offering that response.  (In fact, it's an explicit example given in section 2!)  You opt in to supporting this specification by having a resource at /.well-known/http-opportunistic, unless we wanted to mint a new a new Alt-Svc parameter for the origin and only host the resource on the alternative.

I agree with Kari as well that the text as-written applies to http:// schemed URIs being served over any TLS-based transport.  We might want to generalize that latter section to something like "over a connection consistent with the https:// scheme" or something like that.

More generally, I still disagree with the quoted MUST NOT on the grounds that it's unenforceable and not a hard requirement for interoperability.  Clients that implement only RFC 7838 will inherently violate the MUST NOT, and the server has no way of distinguishing those clients from implementations of this spec.  SHOULD NOT acknowledges that it's undetectable, while still emphasizing that there are risks associated to doing it this way.

Taking a step back, what is the list of ports actually buying us now?  The port can be obtained by the client from the Alt-Svc header.  The fact that the port is legitimate and not hijacked is verified by finding that it has a certificate.  What we're actually confirming is that the origin supports mixed schemes.  The lifetime is already present in the Alt-Svc advertisement, and I haven't heard a compelling reason to have a separate lifetime.  Should we just define SETTINGS_MIXED_SCHEME_PERMITTED and call it a day?

-----Original Message-----
From: [email-masked] [mailto:[email-masked]] On Behalf Of Kari hurtta
Sent: Tuesday, October 4, 2016 9:03 AM
To: HTTP working group mailing list <[email-masked]>
Cc: Kari hurtta <[email-masked]>
Subject: Re: I-D Action: draft-ietf-httpbis-http2-encryption-07.txt

This allows also other than "h2" (for example "http/1.1", which is HTTP/1.1 over TLS).

What part of this specification is valid when prococol identifier is not "h2" ?

/ Kari Hurtta

---

From: Kari Hurtta <[email-masked]>
Date: Wed, 5 Oct 2016 07:51:50 +0300 (EEST)

Mike Bishop <[email-masked]>: (Tue Oct  4 20:38:45 2016)

> Taking a step back, what is the list of ports actually buying us now?  The port can be obtained by the client from the Alt-Svc header.  The fact that the port is legitimate and not hijacked is veri…

Hmm.

SETTINGS_MIXED_SCHEME_PERMITTED is per connection. I assume that HTTP/2
server sends it on SETTINGS frame to HTTP/2 client (similar than what
I contemplated for SETTINGS_WEBSOCKET_CAPABLE at
https://lists.w3.org/Archives/Public/ietf-http-wg/2016OctDec/0033.html )

http-opportunistic response tells here that given port for that
origin handles http -scheme when sent via TLS. 

connection apply probably for several origins. TLS connection
may be terminated by reverse proxy. And different origins
are served by different processes or servers behind of
reverse proxy.

I guess that SETTINGS_MIXED_SCHEME_PERMITTED is too wide.

"tls-ports"  should perhaps now be "mixed-scheme-listeners" 
giving [ "alternative-server:port" ].

/ Kari Hurtta

---

From: Patrick McManus <[email-masked]>
Date: Wed, 5 Oct 2016 10:53:32 +0200

I think I agree with Kari - this is per origin and not per connection..
having implemented the .wk thing I found it pretty workable and the server
side folks liked that this could be done with simply configuration to
reflect origin policy via headers and .wk rather than a protocol extension.

On Wed, Oct 5, 2016 at 6:51 AM, Kari Hurtta <[email-masked]>
wrote:

> > Taking a step back, what is the list of ports actually buying us now?
> The port can be obtained by the client from the Alt-Svc header.  The fact
> that the port is legitimate and not hijacked is verified by finding that it
> has a certificate.  What we're actually confirming is that the origin
> supports mixed schemes.  The lifetime is already present in the Alt-Svc
> advertisement, and I haven't heard a compelling reason to have a separate
> lifetime.  Should we just define SETTINGS_MIXED_SCHEME_PERMITTED and call
> it a day?
>
> Hmm.
>

---

From: Martin Thomson <[email-masked]>
Date: Wed, 5 Oct 2016 23:22:50 +1100

On 5 October 2016 at 04:38, Mike Bishop <[email-masked]> wrote:
> Should we just define SETTINGS_MIXED_SCHEME_PERMITTED and call it a day?

I believe that Julian was the one that observed that h2 isn't any more
special than http/1.1 here.  Julian?

FWIW, I can live with this.  It's certainly a LOT simpler.  Only
servers with modern stacks are going to handle this properly, and
coupling it to h2 doesn't hurt that much.

---

From: Julian Reschke <[email-masked]>
Date: Wed, 5 Oct 2016 14:32:07 +0200

> coupling it to h2 doesn't hurt that much.

I have to admit that I'm not up-to-date with respect to this spec.

That said, if the spec can be made simpler by just treating HTTP/1.1 and 
HTTP/2 the same this sounds like a win to me.

Best regards, Julian

---

From: Martin Thomson <[email-masked]>
Date: Wed, 5 Oct 2016 23:43:13 +1100

And now that I read this thread, I find that the point about origins
over connections is pretty convincing.  I should read all before
committing to mistakes :)

However, perhaps there is some simplification to be salvaged.  I think
that Mike's observation suggests that we can remove "tls-ports".  Once
the TLS-enabled port acknowledges that it understand that it can
receive requests for http://<foo> then maybe that's enough (in
addition to it having a valid certificate, that is).

And, while I'm on the topic, "lifetime" is a bit jarring now that we
don't have a commitment.  To that end, a simpler formulation suggests
itself:

[ "http://example.com", "http://example.com:5602" ]

That should make Mark happy about not having to reconcile "lifetime"
with the cache freshness lifetime.

On 5 October 2016 at 19:53, Patrick McManus <[email-masked]> wrote:
>> > lifetime.  Should we just define SETTINGS_MIXED_SCHEME_PERMITTED and call it
>> > a day?
>>
>> Hmm.
>>

---

From: Kari Hurtta <[email-masked]>
Date: Wed, 5 Oct 2016 16:36:10 +0300 (EEST)

Martin Thomson <[email-masked]>: (Wed Oct  5 15:43:13 2016)
> with the cache freshness lifetime.

I asked

> >> giving [ "alternative-server:port" ].

because should we really say that particular alternative server / port
combination for given origin supports http: -scheme over TLS.

Particular alternative server / port may be reverse proxy
where behind of it there is several origins on different servers.

But also for particular origin there may be several 
alternative servers which are not equal.

Simple?

/ Kari Hurtta

---

From: Martin Thomson <[email-masked]>
Date: Thu, 6 Oct 2016 01:07:16 +1100

> combination for given origin supports http: -scheme over TLS.

I interpreted that as:

  { "http://example.com": {
      "mixed-scheme-listeners": [ "example.net:767", "example.com:3324" ]
    },
    "http://other.example.com" { ... }
  }

This is saying that "http://example.com" is served (in addition to the
cleartext version) on those alternatives.

Whereas I was suggesting just taking the keys from the top-level object:

  [ "https://example.com", "http://other.example.com" ]

But I realize that this information is better obtained more simply
because you need to make a request for a .wk resource on every origin
you are interested in:

  GET http://example.com/.well-known/http-opportunistic HTTP/1.1
  Host: example.com

  200 OK
  Content-Length: 0
  Cache-Control: max-age=123

> alternative servers which are not equal.

Not sure that I follow: are you suggesting that the .wk resource would
advertise the other origins, or that we need some sort of additional
protection?

---

From: Kari Hurtta <[email-masked]>
Date: Wed, 5 Oct 2016 19:16:32 +0300 (EEST)

Martin Thomson <[email-masked]>: (Wed Oct  5 17:07:16 2016)
>     "http://other.example.com" { ... }

Yes.
 
> cleartext version) on those alternatives.

Or actually:

	If Alt-Svc -header field gives this alternative, then
	this alternative (for that origin) is safe to use
	for http: -scheme via TLS (assuming that thhis
	alternative service returns same /.well-known/http-opportunistic
	responce that origin).

〔removed 〕

> advertise the other origins, or that we need some sort of additional

/.well-known/http-opportunistic list there origins which share
same /.well-known/http-opportunistic -file or resource.

For particular origin /.well-known/http-opportunistic list these
potential alternatice service name and port, which are safe for
http: -scheme over TLS.

This is additional protection.  SETTINGS_MIXED_SCHEME_PERMITTED
take account that all alternatice services for given origin
are not good for http: -scheme over TLS, but it does not
take account that connection is shared with several origins.

If /.well-known/http-opportunistic list only origins, then
it does not take account that all alternative services
are not hood for http: -scheme over TLS.

( I assume that alternative services are good for
  https: -scheme and they are valid certificate
  and some subset of url -path namespace is
  shared between http: and https: -scheme. 
  But /login is not good for http: -scheme.
)

/ Kari Hurtta

---

From: Mike Bishop <[email-masked]>
Date: Wed, 5 Oct 2016 17:28:20 +0000

I'm having trouble envisioning the scenario where you need to split this by origin, though.  Our concerns here are about server implementations that ignore the scheme component and simply rely on the incoming port to provide that information, right?.  That means you need to get that information on a port-by-port (i.e. server/connection) basis.  Is there a scenario where alternate.example.com:443 is capable of parsing mixed-scheme requests for one origin, but blind to it for another?  Here are the cases I can think of:

  - Actual server with multiple origins:  It may or may not be configured to *serve* http:// scheme for all origins from that port, but that's indicated by the Alt-Svc headers pointing to it.  Mistaken requests would get a 421.
  - TLS-terminating load balancer:  The connection inside TLS will still reach a single back-end server, so see previous item.
  - HTTP reverse proxy:  The sites behind it may indeed have different capabilities, but that's strictly a function of how the reverse proxy obtains the resources, not something the client needs to validate.

As for moving forward with this, I think it depends on just what we're trying to validate.  Let's agree on the question before we argue about the answer.  Is it:

  - This host is authorized to serve the content for http://example.com?  That's RFC 7838 -- we're done.
  - This host can serve the content for http://example.com and is smart enough not to get confused when scheme and port don't match?  Again, that's RFC 7838 ("mitigate ... by refraining from advertising alternative services for insecure schemes.").  But if you want to enable clients to double-check the origin administrators, let the alternative declare that it's scheme-aware, whether by existence of a .w-k resource or a connection setting.
  - This host can serve content for both http://example.com *and* https://example.com *and* http://other.example.com on the same connection without confusing them all?  That seems to be implied by the previous one.
  - This host *consents* to serve http://example.com?  Seems implicit in responding to requests.  What does anyone gain by checking before sending requests versus trying the requests and maybe getting 421s?

Basically, we've simplified this greatly, and I like that.  But we've simplified it so much that I'm no longer clear what problem we have left to solve. Can someone ELI5?

-----Original Message-----
From: [email-masked] [mailto:[email-masked]] On Behalf Of Kari Hurtta
Sent: Wednesday, October 5, 2016 9:17 AM
To: Martin Thomson <[email-masked]>
Cc: Kari Hurtta <[email-masked]>; Patrick McManus <[email-masked]>; Mike Bishop <[email-masked]>; HTTP working group mailing list <[email-masked]>
Subject: Re: SETTINGS_MIXED_SCHEME_PERMITTED | Re: I-D Action: draft-ietf-httpbis-http2-encryption-07.txt

> > because should we really say that particular alternative server / 
> > port combination for given origin supports http: -scheme over TLS.
> 
> I interpreted that as:
> 

Yes.

Or actually:

〔removed 〕

> > But also for particular origin there may be several alternative 
> > servers which are not equal.
> 

/.well-known/http-opportunistic list there origins which share same /.well-known/http-opportunistic -file or resource.

For particular origin /.well-known/http-opportunistic list these potential alternatice service name and port, which are safe for
http: -scheme over TLS.

This is additional protection.  SETTINGS_MIXED_SCHEME_PERMITTED take account that all alternatice services for given origin are not good for http: -scheme over TLS, but it does not take account that connection is shared with several origins.

If /.well-known/http-opportunistic list only origins, then it does not take account that all alternative services are not hood for http: -scheme over TLS.

/ Kari Hurtta

---

From: Kari Hurtta <[email-masked]>
Date: Wed, 5 Oct 2016 22:33:37 +0300 (EEST)

Mike Bishop <[email-masked]>: (Wed Oct  5 20:28:20 2016)

  >> I guess that SETTINGS_MIXED_SCHEME_PERMITTED is too wide.

Yes, that depends what you want validate.

I was envisioning that selection of back end server spool
on reverse proxy / load balancer is function of origin.

( Yes, this imply that TLS is terminated here )

Effectively you are saying that selection of back 
end server spool on reverse proxy / load balancer 
must be function of origin AND scheme. Or that
that reverse proxy / load balancer must check scheme.

Yes, it is possible to require that SETTINGS_MIXED_SCHEME_PERMITTED
is not sent if reverse proxy / load balancer does not
check itself scheme.

If reverse proxy / load balancer checks scheme and
found that http: is used, it need get SETTINGS_MIXED_SCHEME_PERMITTED
from backend server (if HTTP/2 is used) or use
white list for secure backend servers / pools
or refuse request.

White list tells that which backend servers / pools
check scheme, in that case http:  -request can be
sent ot here.

If selection of back end server / server pool is
function of origin AND scheme, then request
can be sent to that server / pool which is 
for http: -scheme.

> Again, that's RFC 7838 ("mitigate ... by refraining from advertising alternative services for insecure schemes.").

That is

|   refraining from advertising alternative services for insecure schemes
|   (for example, HTTP).

And whole draft is about advertising alternative services for
http -scheme.

I'm really confused.

> Can someone ELI5?

I do not found that from dictionary.

/ Kari Hurtta

---

From: Mike Bishop <[email-masked]>
Date: Wed, 5 Oct 2016 19:54:03 +0000

Well, origin includes scheme, so yes -- if it's terminating HTTP and switching on origin, that means it's looking at the scheme.  That doesn't imply it needs to pass through the MIXED_SCHEME or whatever from the back-end, since it will have its own connections to the back-end servers.  Those will control whether the reverse proxy can mix scheme in its connections to the back end servers, but that doesn't affect whether it supports a mixed scheme on its front.  It will have a potentially-complex set of rules on what requests get served from which back-end server and how.

If it's just a load balancer, possibly terminating TLS, then the HTTP connection terminates at a single back-end, which either supports a mix or not.  In this case, the load balancer would be switching on hostname, not origin, if that.

As to the last, my point is that this document is describing how an alternative can indicate that it doesn't have the problems called out in RFC 7838 section 9.5.  But that section already says, in effect, "don't point to an alternative that has this problem."  So I'm not clear what new additional information is being conveyed here, other than that the origin's Alt-Svc header wasn't sent in error.

(ELI5 => "Explain Like I'm 5" => give me a very simple explanation)

-----Original Message-----
From: [email-masked] [mailto:[email-masked]] On Behalf Of Kari Hurtta
Sent: Wednesday, October 5, 2016 12:34 PM
To: Mike Bishop <[email-masked]>
Cc: Kari Hurtta <[email-masked]>; Martin Thomson <[email-masked]>; Patrick McManus <[email-masked]>; HTTP working group mailing list <[email-masked]>
Subject: Re: SETTINGS_MIXED_SCHEME_PERMITTED | Re: I-D Action: draft-ietf-httpbis-http2-encryption-07.txt

I was envisioning that selection of back end server spool on reverse proxy / load balancer is function of origin.

Effectively you are saying that selection of back end server spool on reverse proxy / load balancer must be function of origin AND scheme. Or that that reverse proxy / load balancer must check scheme.

Yes, it is possible to require that SETTINGS_MIXED_SCHEME_PERMITTED is not sent if reverse proxy / load balancer does not check itself scheme.

If reverse proxy / load balancer checks scheme and found that http: is used, it need get SETTINGS_MIXED_SCHEME_PERMITTED from backend server (if HTTP/2 is used) or use white list for secure backend servers / pools or refuse request.

White list tells that which backend servers / pools check scheme, in that case http:  -request can be sent ot here.

If selection of back end server / server pool is function of origin AND scheme, then request can be sent to that server / pool which is for http: -scheme.

That is

I'm really confused.

/ Kari Hurtta

---

From: Ilari Liusvaara <[email-masked]>
Date: Wed, 5 Oct 2016 23:31:06 +0300

>   - This host *consents* to serve http://example.com?  Seems implicit in responding to requests.  What does anyone gain by checking before sending requests versus trying the requests and maybe gett…

Then there is the problem what to do if client sends a :scheme value
the server/rproxy does not know anything about, not even how to properly
reject it.

In the original proposal, I proposed adding a new stream error type for
rejecting such streams.

-Ilari

---

From: Martin Thomson <[email-masked]>
Date: Thu, 6 Oct 2016 11:35:09 +1100

I'll try, but it might be ELI15...

> Basically, we've simplified this greatly, and I like that.  But we've simplified it so much that I'm no longer clear what problem we have left to solve. Can someone ELI5?

A client learns that a server has a "secure" alternative.  This
implies that clients can send "not-secure" requests to a "secure"
server.

The client wants to know that this alternative understands what it
means when it sends a "not-secure" request to that server.  This is
because some "secure" servers can be confused by a "not-secure"
request. They might think that it is "secure" and do the wrong thing.

We need to find a way to ask the "secure" server if it is OK with
getting "not-secure" requests.

>   - This host is authorized to serve the content for http://example.com?  That's RFC 7838 -- we're done.

I wish.

>   - This host can serve the content for http://example.com and is smart enough not to get confused when scheme and port don't match?  Again, that's RFC 7838 ("mitigate ... by refraining from advert…

It's hard to know whether a server is confused just by making regular requests.

>   - This host can serve content for both http://example.com *and* https://example.com *and* http://other.example.com on the same connection without confusing them all?  That seems to be implied by…

I think that Kari was hinting at a problem where a load balancer
terminates TLS and then routes based on the Host header alone.  The
back-end servers aren't all equally capable of distinguishing between
"secure" and "not-secure".

That suggests to me that you probably want proof positive for all
origins separately, as we discussed.

>   - This host *consents* to serve http://example.com?  Seems implicit in responding to requests.  What does anyone gain by checking before sending requests versus trying the requests and maybe gett…

See above regarding confusion.  Just providing a response isn't enough.

---

Here's my concrete proposal (as I made earlier):

"""
Before using a secure alternative for an http:// origin, a client MUST
first request /.well-known/http-opportunistic at that origin.  If this
resource exists and a not-stale 2xx response is obtained, then
requests for the origin MAY be directed toward the secure alternative.
The contents of this resource do not matter.  If multiple http://
origins are coalesced onto the same connection to a secure
alternative, a client MUST obtain an http-opportunistic resource from
each origin separately.
"""

You might insist on greater proof here (a Content-Location header
field would be stronger proof, or you could mandate some format for
the response body), but I don't believe that to be necessary.  Once
the http-opportunistic resource exists, then we have proof that the
server has opted in.

This does mean that in co-hosted situations an audit is recommended to
ensure that there are no resources for which there are a) necessary
variations between https:// and http:// resources on the same path and
b) confusion might be possible.  The server operator then needs to
choose whether to disable http-opportunistic just on the affected
origins or to disable the feature entirely.

---

From: Erik Nygren <[email-masked]>
Date: Wed, 5 Oct 2016 21:12:05 -0400

Can we just solve this with the ORIGIN frame?
In particular, define that clients must not request with http scheme
unless an ORIGIN frame has advertised it?
What gets presented in the ORIGIN frame looks remarkably close to what
Martin listed
above as the bare-minimum version of the .wk resource that we've
effectively boiled things down to:

The primary down-side that I see is that this doesn't provide a way
to specify allowing both http and https but just not mixed over the same
connection.
(I guess we could have a flag on the ORIGIN frame for ALLOW_MIXED_SCHEME,
although this could be tricky if clients send before getting the frame.)

Pros of ORIGIN frame:
* Can be server-sends-first (unlike .wk)
* Might be possible to define that if hostname=origin and if both
https://hostname and http://hostname is sent as ORIGIN frames that both can
use the same connection even without AltSvc?  (This could potentially help
protect sites with mixed-scheme resources without needing to have anything
sent cleartext.)

Cons of ORIGIN frame:
* Requires server/protocol side changes beyond putting a file in-place
(which may be just fine)

         Erik

On Wed, Oct 5, 2016 at 8:35 PM, Martin Thomson <[email-masked]>
wrote:

> > Basically, we've simplified this greatly, and I like that.  But we've
> simplified it so much that I'm no longer clear what problem we have left to
> solve. Can someone ELI5?
>

---

From: Martin Thomson <[email-masked]>
Date: Thu, 6 Oct 2016 14:01:50 +1100

> * Requires server/protocol side changes beyond putting a file in-place

Doesn't work for HTTP/1.1.

We could go for both...

---

From: Kari Hurtta <[email-masked]>
Date: Thu, 6 Oct 2016 06:29:10 +0300 (EEST)

Mike Bishop <[email-masked]>: (Wed Oct  5 22:54:03 2016)
> Well, origin includes scheme, so yes -- 

Yes, you are correct. My mistake.

> In this case, the load balancer would be switching on hostname, not origin, if that.

Yes. I wrote that sloppy.

/ Kari Hurtta

---

From: Kari Hurtta <[email-masked]>
Date: Thu, 6 Oct 2016 06:57:07 +0300 (EEST)

Martin Thomson <[email-masked]>: (Thu Oct  6 03:35:09 2016)

> "secure" and "not-secure".

Yes. Host: -header alone or on case of HTTP/2 also :authority
can be used (if there is it).

SETTINGS_MIXED_SCHEME_PERMITTED RFC may be written that way
that  load balancer MUST NOT send it, if load balancer 
works with Host: / :authority alone. 

It is harder to say when SETTINGS_MIXED_SCHEME_PERMITTED = 1
can be sent.

Effectively there HTTP/2 over TLS requires quite
much new software if SETTINGS_MIXED_SCHEME_PERMITTED
route is used. Perhaps that is good.

Ilari Liusvaara:

| Then there is the problem what to do if client sends a :scheme value
| the server/rproxy does not know anything about, not even how to properly
| reject it.
| 
| In the original proposal, I proposed adding a new stream error type for
| rejecting such streams.

Hypothetical SETTINGS_MIXED_SCHEME_PERMITTED RFC  need specify
that error code.

/ Kari Hurtta

---

From: Mike Bishop <[email-masked]>
Date: Thu, 6 Oct 2016 18:12:24 +0000

Okay, so we are basically trying to backfill a possible administrative mistake by verifying that the server processes scheme as part of origin.  So an administrator MUST BUT WE KNOW YOU WON'T only put this resource in place if their server is properly configured to handle a scheme inconsistent with the port.  After they already have to opt in by sending the Alt-Svc header on the origin in the first place.  I'm lacking confidence that this check actually assures anything except that the administrator wants it to work, and we already know that from the Alt-Svc header.

If we want to *validate* that the server is handling scheme properly, then we need to have different content at http:// and https:// and check that we get the right one over the right scheme.  If an identical resource is present on both schemes, retrieving it doesn't prove anything, and I continue to doubt that it tells us anything about administrative intent that we don't already know from the Alt-Svc header being emitted.

What if http://.../.w-k/h-o MUST exist (200) and https:// .../.w-k/h-o MUST NOT exist (404)?  If a client checks both of those things, it has actually proven scheme handling rather than just asked the server to promise.

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, October 5, 2016 5:35 PM
To: Mike Bishop <[email-masked]>
Cc: Kari Hurtta <[email-masked]>; Patrick McManus <[email-masked]>; HTTP working group mailing list <[email-masked]>
Subject: Re: SETTINGS_MIXED_SCHEME_PERMITTED | Re: I-D Action: draft-ietf-httpbis-http2-encryption-07.txt

> Basically, we've simplified this greatly, and I like that.  But we've simplified it so much that I'm no longer clear what problem we have left to solve. Can someone ELI5?

A client learns that a server has a "secure" alternative.  This implies that clients can send "not-secure" requests to a "secure"
server.

The client wants to know that this alternative understands what it means when it sends a "not-secure" request to that server.  This is because some "secure" servers can be confused by a "not-secure"
request. They might think that it is "secure" and do the wrong thing.

We need to find a way to ask the "secure" server if it is OK with getting "not-secure" requests.

I wish.

>   - This host can serve content for both http://example.com *and* https://example.com *and* http://other.example.com on the same connection without confusing them all?  That seems to be implied by…

I think that Kari was hinting at a problem where a load balancer terminates TLS and then routes based on the Host header alone.  The back-end servers aren't all equally capable of distinguishing between "secure" and "not-secure".

That suggests to me that you probably want proof positive for all origins separately, as we discussed.

---

"""
Before using a secure alternative for an http:// origin, a client MUST first request /.well-known/http-opportunistic at that origin.  If this resource exists and a not-stale 2xx response is obtained, then requests for the origin MAY be directed toward the secure alternative.
The contents of this resource do not matter.  If multiple http:// origins are coalesced onto the same connection to a secure alternative, a client MUST obtain an http-opportunistic resource from each origin separately.
"""

You might insist on greater proof here (a Content-Location header field would be stronger proof, or you could mandate some format for the response body), but I don't believe that to be necessary.  Once the http-opportunistic resource exists, then we have proof that the server has opted in.

This does mean that in co-hosted situations an audit is recommended to ensure that there are no resources for which there are a) necessary variations between https:// and http:// resources on the same path and
b) confusion might be possible.  The server operator then needs to choose whether to disable http-opportunistic just on the affected origins or to disable the feature entirely.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 7 Oct 2016 11:38:53 +1100

> Okay, so we are basically trying to backfill a possible administrative mistake by verifying that the server processes scheme as part of origin.  So an administrator MUST BUT WE KNOW YOU WON'T only…

There's one very important difference: the .well-known response is
authenticated.  An attacker can forge an Alt-Svc header.

And in any case, if the administrator lies, they are at least taking
responsibility for the error, that's important too.

The MUST NOT exist for the https:// variant is a neat trick, and it
would increase confidence, but I don't think that it proves anything
other than the fact that THAT specific resource is handled correctly
(as you know, much of this can hinge not on the generic code in the
server, but on code specific to a resource).

---

From: Kari Hurtta <[email-masked]>
Date: Fri, 7 Oct 2016 07:21:23 +0300 (EEST)

> alternative, a client MUST obtain an http-opportunistic resource from

Side note:

I do not not like existing but empty resource test.

I have seen some instructions (for load balancer)
that how to convert http 404 to http 200 with empty page
(or response).

IMHO that conversion is very bad and stupid idea.

Mike Bishop:

| What if http://.../.w-k/h-o MUST exist (200) and 
| https:// .../.w-k/h-o MUST NOT exist (404)?  If a client 
| checks both of those things, it has actually proven scheme 
| handling rather than just asked the server to 
| promise.

Exists, is not empty and does not look like html -page.

/ Kari Hurtta

---

From: Martin Thomson <[email-masked]>
Date: Fri, 7 Oct 2016 16:11:37 +1100

> that how to convert http 404 to http 200 with empty page

Then insist on it being text that includes the origin.

---

From: Mike Bishop <[email-masked]>
Date: Fri, 7 Oct 2016 05:49:14 +0000

Fair enough that the Alt-Svc could have been inserted by an attacker that knows that particular server is scheme-insensitive and wants to provoke whatever the misbehavior is.  Validating the agreement over TLS for that reason makes more sense to me.  I still would argue that client SHOULD check for this (not MUST) simply because a client could follow the Alt-Svc header without checking .w-k and be perfectly compliant with RFC 7838.  The client isn't requesting additional functionality via Opp-Sec, but gaining a way to double-check the alternative's intent/ability to play along when the initial reference was vulnerable to meddling.  (Unless we're proposing to update RFC 7838 by adding that MUST?)

While I certainly grant that it's possible for apps above the server layer to handle this incorrectly as well, I think a lot of that gets mitigated if the server layer properly tells the app that the requested URL was http://example.com.  (I believe ours actually overrides the scheme as presented, so an app basically never has the chance to get it right.)  While apps are endlessly creative in ways to get things wrong, your odds are at least much better if the server is capable of delivering the correct requested URL to the application.
________________________________
From: Martin Thomson <[email-masked]>
Sent: Thursday, October 6, 2016 10:11:37 PM
To: Kari Hurtta
Cc: Mike Bishop; Patrick McManus; HTTP working group mailing list
Subject: Re: Empty but existing resource | Re: SETTINGS_MIXED_SCHEME_PERMITTED | Re: I-D Action: draft-ietf-httpbis-http2-encryption-07.txt

---

From: Stefan Eissing <[email-masked]>
Date: Fri, 7 Oct 2016 09:24:26 +0200

> Am 06.10.2016 um 20:12 schrieb Mike Bishop <[email-masked]>:
> 
> """

+1

I like this because it avoids the hop-by-hop problem of a SETTING where it is the origin server's responsibility to get it right. And, as Martin noted, Alt-Svc headers are a possible angle of attack if clients have no other means to verify the server capability.

-Stefan

---

From: Patrick McManus <[email-masked]>
Date: Fri, 7 Oct 2016 09:45:46 +0200

On Thu, Oct 6, 2016 at 8:12 PM, Mike Bishop <[email-masked]>
wrote:

> If we want to *validate* that the server is handling scheme properly, then
> we need to have different content at http:// and https:// and check that
> we get the right one over the right scheme.

I don't think that proof is necessary for something like .wk where the
resource has such an explicit meaning. The meaning of the .wk is that http
over tls is OK, it doesn't mean the server MUST treat the resources
differently (just an assurance that not doing so isn't a semantic problem
for their content).

Like Mike, I've tried to make the argument that this step isn't really
required but I've grown weary of the pushback and the cost of doing so has
proven reasonable to me (I've implemented the json thing) so at this point
I would rather go ahead with some kind of check.

I think either the 200 or the json are acceptable here - let's decide.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 7 Oct 2016 19:34:02 +1100

On 7 October 2016 at 16:49, Mike Bishop <[email-masked]> wrote:
> The client isn't requesting additional functionality via Opp-Sec, but
> gaining a way to double-check the alternative's intent/ability to play along
> when the initial reference was vulnerable to meddling.  (Unless we're
> proposing to update RFC 7838 by adding that MUST?)

Nah, updates aren't necessary, we're just looking for belts AND braces
on this stuff.  We have some evidence that scheme isn't routinely
looked at in the critical parts of the stack, so this is in response
to that.  Yep, it's paranoid.

---

From: Martin Thomson <[email-masked]>
Date: Fri, 7 Oct 2016 20:54:13 +1100

> I think either the 200 or the json are acceptable here - let's decide.

Me too.  I think that we all now understand the parameters and we have
a decent chance of being able to document the hazards, so let's pick.
Shall I get a coin?

---

From: Patrick McManus <[email-masked]>
Date: Fri, 7 Oct 2016 16:33:41 +0200

> a decent chance of being able to document the hazards, so let's pick.
can we consider MUST serve json, MUST verify 200, SHOULD verify json? This
recognizes that the json burden is harder on the client - the server can
just publish a fixed string.

This also recognizes that the party being protected here is the client.
(Nothing in this approach prevents an attacking MITM from just hijacking
regular plaintext h1 and proxying it to port 443 with an http scheme on the
server in the total absence of a .wk.. nothing unless the attacker is
afraid of being declared a non compliant attacker :))

-P

---

From: Kari hurtta <[email-masked]>
Date: Sat, 8 Oct 2016 08:42:00 +0300 (EEST)

> But this part is specific to "h2".

Continuing.

 ⇒

  When client send "http" requests over a TLS connection request
  request MUST include scheme. This means that when used with 
  protocol identifier "http/1.1" (TTP/1.1 over TLS), request uses 
  absoluteURI -form.

  Client SHOULD NOT use a http-opportunistic response if requesting
  of it invoked http-redirect.

  Clients MUST NOT send "http" requests over a TLS connection, unless
  they have obtained a valid http-opportunistic response for an origin 
  (as per Section 2.3), and:

(Also "SHOULD NOT" was suggested, I have no strong position for this.)

|   o  The chosen alternative service presents a certificate that is
|      valid for the origin, as per [RFC2818] (this also establishes
|      "reasonable assurances" for the purposes of {RFC7838}}), and

  ⇒ (no change)

|   o  The origin object of the http-opportunistic response has a `tls-
|      ports' member, whose value is an array of numbers, one of which
|      matches the port of the alternative service in question, and

  ⇒

   o  The origin object of the http-opportunistic response has a 
      "http-scheme-listeners" member, whose value is an array of 
      strings, one of which matches the name and port number of the 
      alternative service in question (on form "name:port"), and

( I suggested "mixed-scheme-listeners" -name first.
  https://lists.w3.org/Archives/Public/ietf-http-wg/2016OctDec/0056.html
)

|   o  The chosen alternative service returns the same representation as
|      the origin did for the http-opportunistic resource.

   ⇒ (no change)  

|   For example, this request/response pair would allow reqeusts for the
|   origin "http://www.example.com" to be sent to an alternative service
|   on port 443 or 8000 of the host "www.example.com":

   ⇒ 

   For example, this request/response pair would allow reqeusts for the
   origin "http://www.example.com" to be sent to an alternative service
   on port 443 of the host "www.example.com" or on port 8000 of the host 
   "www2.example.com":

   ⇒ 

   HTTP/1.1 200 OK

   {
     "http://www.example.com": {
       "http-scheme-listeners": [ "www.example.com:443", "www2.example.com:8000" ],
       "lifetime": 2592000
     }
   }

(Should "lifetime" also be dropped?)

2.3.  The "http-opportunistic" well-known URI
https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07#section-2.3

|   o  The origin object has a "lifetime" member, whose value is a number
|      indicating the number of seconds which the origin object is valid
|      for (hereafter, the "origin object lifetime"), and
|
|   o  The origin object lifetime is greater than the "current_age" (as
|      per [RFC7234], Section 4.2.3).
|
|   Note that origin object lifetime might differ from the freshness
|   lifetime of the response.

It is noted "lifetime" member is no longer needed because there is no commit.
Then this request some rewrite, but I not try it now.

This means that http-opportunistic response have members
"mixed-scheme" and "http-scheme-listeners" members on the 
the origin object.

/ Kari Hurtta

---

From: Kari hurtta <[email-masked]>
Date: Sun, 9 Oct 2016 10:34:16 +0300 (EEST)

> What if http://.../.w-k/h-o MUST exist (200) and https:// .../.w-k/h-o MUST NOT exist (404)?  If a client checks both of those things, it has actually proven scheme handling rather than just asked…

( status 200 with empty /.well-known/http-opportunistic
  or html /.well-known/http-opportunistic does not
  really tell that http: -scheme is handled. It MUST
  also return application/json Content-Type and at least
  json SHOULD be parsed and verified)

So 

from origin and alternative service can be done same time. These
two MUST be same.

GET https://www.example.com/.well-known/http-opportunistic HTTP/1.1

must either use new connection or if same connection is
used first need wait that http-opportunistic is parsed
and there is "mixed-scheme" member with value "true"
for the origin "http://www.example.com/".

I think that following should be allowed for not exist:

	404 Not Found
	TBD1 Scheme Not Allowed       (this RFC)
	501 Not Implemented

I'm not sure about
	421 Misdirected Request

2.2.  Interaction with "https" URIs
https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07#section-2.3

|   Because of the risk of server confusion about individual requests'
|   schemes (see Section 4.4), clients MUST NOT send "http" requests on a
|   connection that has previously been used for "https" requests, unless
|   the http-opportunistic origin object Section 2.3 fetched over that
|   connection has a "mixed-scheme" member whose value is "true".

I think that RFC can also require opposite.

Add:

   And clients MUST NOT send "https" requests on a connection that has 
   previously been used for "http" requests, unless the http-opportunistic 
   origin object has a "mixed-scheme" member whose value is "true"

That https: not exist -check perhaps can be on that section also.

   Client MUST check that "http-opportunistic" well-known URI is
   not retriable with using "https" scheme for an alternative
   service before using for "http" origin. 

   Note: If the http-opportunistic origin object has no "mixed-scheme" 
   member with value "true", then check need to be done with different 
   connection than what was used for getting http-opportunistic response
   for "http" scheme.

   Client SHOULD NOT use selected alternative service for "http" origin
   unless "http-opportunistic" well-known URI via "https" scheme
   returned HTTP status code

     ∘ 404 (Not Found), or
     ∘ TBD1 (Scheme Not Allowed), or
     ∘ 501 (Not Implemented).

( SHOULD NOT so that there is some leeway for what 
  HTTP status codes are considered to be not existing
  resource. )

  The TBD1 (Scheme Not Allowed) status code indicates that
  used scheme is not allowed for the request.

3.  IANA Considerations
https://tools.ietf.org/html/draft-ietf-httpbis-http2-encryption-07#section-3

add:

  This specification registers a (HTTP) Status Codes:

  [TO BE REMOVED: Hypertext Transfer Protocol (HTTP) Status Code Registry
   http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml ]

   +-------+-------------------------------+-------------+
   | Value | Description                   | Reference   |
   +-------+-------------------------------+-------------+
   | TBD1  | Scheme Not Allowed            | Section 2.2 |
   | TBD2  | Scheme Required               | Section 2.1 |
   +-------+-------------------------------+-------------+

   [TO BE REMOVED: TBD1 and TBD2 are from 4xx range. ]

I wrote at  https://lists.w3.org/Archives/Public/ietf-http-wg/2016OctDec/0097.html

|  When client send "http" requests over a TLS connection request
|  request MUST include scheme. This means that when used with 
|  protocol identifier "http/1.1" (TTP/1.1 over TLS), request uses 
|  absoluteURI -form.

for "2.1.  Alternative Server Opt-In"
( Better title: 2.1.   Using "http" scheme over TLS connection)

This chapter can include:

  Server MAY return http status code TBD2 (Scheme Required) 
  if request does not include scheme.

  The TBD2 (Scheme Required) status code indicates
  that scheme is required for request. This means that
  server requires absoluteURI -form to be used for
  HTTP/1.1 -request.

/ Kari Hurtta

---

From: Martin Thomson <[email-masked]>
Date: Mon, 10 Oct 2016 10:17:08 +1100

>         421 Misdirected Request

421 is actually the right response code when the server is sure that
it is not authoritative for an origin.  However, this is case where
the server probably IS authoritative, we just want the resource to not
exist. (If you accept the premise, I don't think that it's a necessary
change, see Patrick's email about who is being protected).

>    origin object has a "mixed-scheme" member whose value is "true"

I disagree.  The point of all this mucking around is to make it clear
that special behaviour is permitted, making https requests over an
authenticated TLS connection is perfectly normal and expected.

---

From: Kari Hurtta <[email-masked]>
Date: Mon, 10 Oct 2016 07:45:40 +0300 (EEST)

Martin Thomson <[email-masked]>: (Mon Oct 10 02:17:08 2016)
> authenticated TLS connection is perfectly normal and expected.

After one "https" reguest that apply:

|                            clients MUST NOT send "http" requests on a
|    connection that has previously been used for "https" requests,

So it is unusable for "http".

And if "http" and "https" are send consecutive on "h2", which
one is executed first?  

What is reason that  "mixed-scheme" is "true" requirement?

Is reason that
	∘ confusion happens if "http" follows "https", or 
	∘ scheme is determined only on first request ?

If any "https" can cause confusion, then there is also
danger on sequence "http" and then "https" assuming that
first is not completed before send is requested.

/ Kari Hurtta

---

From: Martin Thomson <[email-masked]>
Date: Mon, 10 Oct 2016 15:55:17 +1100

> |    connection that has previously been used for "https" requests,

The point of this is to cover off any problems that might arise from
connection reuse.  It's clumsy.  I think that it should be reworded:
clients MUST NOT send "http" requests on a connection that would
ordinarily be used for "https" requests unless the http-opportunistic
origin object [...]

If scheme is determined on the first request and that causes this
check to pass, then we're going to get false positives.  Remember:
we're incapable of detecting all cases where the server decides to do
crazy things - I'm sure that I can devise a server architecture that
will fail for any solution we devise - we have to instead take steps
that we think are reasonable.

---

From: Kari Hurtta <[email-masked]>
Date: Mon, 10 Oct 2016 08:15:52 +0300 (EEST)

Martin Thomson <[email-masked]>: (Mon Oct 10 07:55:17 2016)
> ordinarily be used for "https" requests unless the http-opportunistic

That looks good.
 
> that we think are reasonable.

I can image real word situation where scheme is checked only
on the first request. Namely load balancer which do routing
decision on first request and then same back end connection
is used for all requests. 

Yes, I can not guess all cases where server does grazy things.

( That is:
    route port 80 to pool1
    route port 443, scheme "http" to pool1
    route port 443, scheme "https" to pool2
)

/ Kari Hurtta

---

From: Martin Thomson <[email-masked]>
Date: Mon, 10 Oct 2016 16:21:36 +1100

> is used for all requests.

Yes, this remains a VERY common configuration, despite all the warnings.